python 爬取华为应用市场评论


Posted in Python onMay 29, 2021

代码分享

整个项目我放在了github上,在python3.7下可以正常使用,如果有什么问题欢迎大家指正。

github项目地址:https://github.com/LSY-C/scrapy_hauweiappstore_comment

分别爬取的一些应用信息以及应用的评论信息,数据结构如下:

python 爬取华为应用市场评论

python 爬取华为应用市场评论

一、安装并创建Scrapy项目

Scrapy官方文档:https://docs.scrapy.org/en/latest/intro/install.html

Scrapy是一个比较好用的python爬虫框架,官方文档写得也比较详细。可以直接运行以下命令安装:

pip install Scrapy

安装完毕后,需要创建Scrapy项目,相当于是一个爬虫项目框架,在想要放置项目的地方打开命令行并输入以下命令会自动创建一个名为[project_name]的文件夹,比如我这里的[project_name]是appstore,文件夹中会自动生成的一些文件。

scrapy startproject appstore
  • appstore/scrapy.cfg中包含了用于启动爬虫的一些基础配置,一般不用管它。
  • appstore/appstore/items.py:定义了爬取到的数据格式类,在这里面创建类来存放爬取到的数据的item格式。
  • appstore/appstore/middlewares.py:定义了爬虫中间键的一些行为,我一般也不会去动它。
  • appstore/appstore/pipelines.py:定义了爬取到item后对其进行的处理。
  • appstore/appstore/settings.py:是爬虫配置文件。
  • appstore/appstore/spiders/:这个目录下存放的是爬虫,也就是向网页发送请求并受到应答然后进行数据处理的过程。

二、爬取应用市场评论过程

爬取网页信息有两个常用的方法:

  • 直接通过xpath解析html文件
  • 依据特定格式构造请求获取json数据进行解析

显然前者更简单方便一些,但是现在许多网页都是动态的,所以后者泛用性更强一些,这里我爬取华为应用市场上所有应用的评论信息主要使用的是后面一种方法。

1. Scrapy爬虫运行流程

首先需要大致了解Scrapy的爬虫是如何运作的,分为以下几个步骤:

  • Step1: 在项目的spiders文件夹中新建一个.py文件,比如huawei.py,一般来说每一个文件代表一个爬虫,也就是对某一个网页的爬取策略。
  • Step2: 创建一个类继承自scrapy.Spider,类中至少需要有name、allowed_domain、start_urls变量以及一个函数parse(self)。其中name是此爬虫的唯一标识,之后启动时通过指定name来判断启动哪个爬虫(因为spiders文件夹中可能包含多个爬虫文件);allowed_domain用来指定当前爬虫可以访问的主域名;start_urls用来指定首先获取的页面,而此获取结果将会交由parse函数进行处理。每个爬虫中的处理函数可能有很多个,命名格式一般是parse_xxx之类的,用来处理多级页面,比如parse处理完主页面之后构造新的请求获取二级页面信息并通过parse_second进行处理,但不管怎么样都会包含一个parse函数。
import scrapy
class HuaWei(scrapy.Spider):
    name = "huawei"
    allowed_domains = ['appstore.huawei.com', 'web-drcn.hispace.dbankcloud.cn']
    start_urls = [
        'https://web-drcn.hispace.dbankcloud.cn/uowap/index?method=internal.getTemplate&serviceType=20&zone=&locale=zh']

    def parse(self, response):
    	pass
  • step3: 爬虫编写好之后,在项目根目录(也就是scrapy.cfg文件的同级目录)打开命令行,并输入以下命令启动爬虫:
scrapy crawl hauwei

2. 页面分析

首先,通过浏览器访问应用市场,分析一下想要爬取网页的基本信息,这里我想要爬取应用市场中所有应用的评论,所以首先需要进入到所有应用的详细界面,然后在详细界面中展开评论进行爬取,基本的思路是:对每一个分类?>对每一个子分类?>展开每一个应用?>获取应用全部评论。

python 爬取华为应用市场评论

python 爬取华为应用市场评论

python 爬取华为应用市场评论

爬取的初始页面是https://appgallery.huawei.com/#/Apps,浏览器中使用F12启动开发者模式,调试网页前端代码,我们希望的是能够找到页面排版的某些规律。

页面分析过程一

我们发现不管在应用分类的选项卡中选择哪一个分类或是子分类,url都不会变。也就是说,选择分类后显示对应的应用列表这一功能是动态实现的,我们没办法通过抓取html中的信息来获取不同分类的应用列表,那么我们只能通过自己构造请求获取json数据的方式爬取信息。
首先,打开调试窗口中的Network选项卡来分析获取不同分类应用列表时的网络数据包:

python 爬取华为应用市场评论

除了第一个数据包以外,后面的都是获取应用图标数据,也就是说第一个数据包里面就包含了应用的其他数据,查看此数据包中的request_url为:

https://web-drcn.hispace.dbankcloud.cn/uowap/index
?method=internal.getTabDetail
&serviceType=20
&reqPageNum=1
&uri=8e62cf6d238c4abdb892b400ff072f43
&maxResults=25
&zone=
&locale=zh

我们直接在浏览器中访问此url,可以得到一个json文件,分析后发现此json文件中包含了列表中应用的信息。点击不同的分类、子分类,获取不同的request_url,我们发现,每一个子分类的request_url都只有uri字段不一样,且默认情况都只显示第1页的25个应用。也就是说我们以此request_url为模板,修改uri字段实现获取不同类别应用列表,修改reqPageNum字段获取列表中的多页应用。

页面分析过程二

手动点进每一个应用的详细界面时,我们发现,不同应用的详细界面的url只有最后的定位有不同,比如腾讯视频与优酷视频这两个应用详细界面的url分别是:

python 爬取华为应用市场评论

多观察几个应用就会发现最后的那一串代码应该是类似于应用唯一标识符一样的东西。而在上一步中,我们可以发现在获取的每个应用信息中包含能够找到这些标识符(‘appid'键的值),于是我在这里尝试直接以这种格式构造url请求获取页面,但是失败了,猜测可能是页面重定向的问题,没办法,只能按部就班地通过其它方式继续分析。
通过F12查看页面排版,每一个app卡片中虽然有app名称以及一些其他信息,但是找不到app详细页面的链接,因为获取应用详细信息功能被写成了使用js动态获取的,因此我们没办法直接从html界面中获取,所以依旧采用构造request_url的方法获取json数据。

python 爬取华为应用市场评论

与分析过程一类似,我们可以获取以下的request_url:

https://web-drcn.hispace.dbankcloud.cn/uowap/index
?method=internal.getTabDetail
&serviceType=20
&reqPageNum=1
&maxResults=25
&uri=app%7CC174391
&shareTo=
&currentUrl=https%253A%252F%252Fappgallery.huawei.com%252F%2523%252Fapp%252FC174391
&accessId=
&appid=C174391
&zone=
&locale=zh

通过此request_url获取的json中包含了应用的详细信息,实际上通过测试,其中的reqPageNum、maxResults、shareTo、currentUrl、accessId、appid、zone、locale字段都是不需要的,而又发现uri字段中后面的“C174391”是当前应用的appid,也就是说我们只需要修改uri字段的“app%7C”后面的字符串为不同应用的appid(可以在分析过程一中的json文件里获取),就可以获取不同应用的详细信息。

页面分析过程三

有了上面两次分析的经验,我们继续来爬取每个应用的评论数据,发现这些数据也是通过js动态获取的,于是继续分析request_url,格式如下:

https://web-drcn.hispace.dbankcloud.cn/uowap/index
?method=internal.user.commenList3
&serviceType=20
&reqPageNum=1
&maxResults=25
&appid=C2002
&version=10.0.0
&zone=
&locale=zh

与之前类似,我们可以通过修改appid字段爬取不同应用的评论,通过修改reqPageNum字段爬取多页评论。

3. 爬虫实现

整个爬取过程就是:构造request_url请求获取json数据?>解析json数据?>构造新的request_url获取json数据?>…
下面是爬虫中的一个处理函数,功能是处理每一个应用的详细信息并构造获取评论的request_url发送新的请求,接下来依次说明其中的关键部分。

def app_parse(self, response):
    """
    解析应用,获取应用名称、描述、资费、版本、开发者,然后转至appcomment_parse进行处理
    :param resonse:
    :return:
    """
    appid = response.meta['appid']
    app_json = json.loads(response.text)
    Name = app_json.get('layoutData')[0].get('dataList')[0].get('name')
    Star = app_json.get('layoutData')[0].get('dataList')[0].get('intro')
    Downloads = app_json.get('layoutData')[0].get('dataList')[0].get('stars')
    Price = app_json.get('layoutData')[3].get('dataList')[0].get('tariffDesc')
    Version = app_json.get('layoutData')[3].get('dataList')[0].get('version')
    Developer = app_json.get('layoutData')[3].get('dataList')[0].get('developer')
    Description = app_json.get('layoutData')[7].get('dataList')[0].get('appIntro').replace('\n', '')
    AppData = AppItem(
        AppId=appid,
        AppName=Name,
        AppDesc=Description,
        AppPrice=Price,
        AppVersion=Version,
        AppDeveloper=Developer,
        AppStar=Star,
        AppDownloads=Downloads
    )
    yield AppData
    for pagenum in range(1, 20):
        request_url = "https://web-drcn.hispace.dbankcloud.cn/uowap/index?method=internal.user.commenList3&serviceType=20&reqPageNum={}&maxResults=25&appid={}&version=10.0.0&zone=&locale=zh".format(
            pagenum, appid)
        yield scrapy.Request(url=request_url, callback=self.appcomment_parse, meta={'appid': appid})

解析json并构造请求

第8行中通过json.loads将响应解析为json格式,并在后续使用键值与index访问里面的信息。

将数据保存在items中

在items.py文件中定义好Item类之后,可以在此新建一个Item对象,并在填入相应的值,将此item返回交由pipeline.py进行处理。

# items.py
class AppItem(scrapy.Item):
    AppId = scrapy.Field()
    AppName = scrapy.Field()
    AppDesc = scrapy.Field()
    AppPrice = scrapy.Field()
    AppVersion = scrapy.Field()
    AppDeveloper = scrapy.Field()
    AppStar = scrapy.Field()
    AppDownloads = scrapy.Field()

yield是python中的一个关键词,与return类似,会让函数返回此关键词修饰的表达式值,与return不同的是,yield在返回一个值后会继续执行后面的代码,而return不会。

构造新的请求

在最后一行中针对所有评论列表构造新的request_url以获取评论信息,并通过scrapy.Request发送请求,其中callback指定用于处理此请求响应的处理函数,而meta中包含了想要传递给callback函数的信息。

item数据的处理

在爬取数据的过程中,处理函数会实时将不同的item返回并交由pipeline进行处理,此时需要在pipeline.py中指定如何处理这些item,比如在此我把数据全都记录入csv表格中。pipeline类中必须定义process_item函数来处理每一个item,而__init__与close_spider都是可选的。

class AppStorePipeline:
    def __init__(self):
        self.app_list = []
        self.comment_list = []

    def process_item(self, item, spider):	# 接收到item时调用的函数
        if isinstance(item, AppItem):
            self.app_list.append(dict(item))
        elif isinstance(item, CommentItem):
            self.comment_list.append(dict(item))
        return item

    def close_spider(self, spider):			# 当爬虫关闭时调用的函数
        df_app = pd.DataFrame(self.app_list)
        df_comment = pd.DataFrame(self.comment_list)
        df_app.to_csv('app_info.csv')
        df_comment.to_csv('comment_info.csv')

以上就是python 爬取华为应用市场评论的详细内容,更多关于python 爬取华为应用市场的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python import用法以及与from...import的区别
May 28 Python
Python Nose框架编写测试用例方法
Oct 26 Python
Python中elasticsearch插入和更新数据的实现方法
Apr 01 Python
python 按照固定长度分割字符串的方法小结
Apr 30 Python
Python基于opencv的图像压缩算法实例分析
May 03 Python
解决Python print 输出文本显示 gbk 编码错误问题
Jul 13 Python
不归路系列:Python入门之旅-一定要注意缩进!!!(推荐)
Apr 16 Python
详解Python静态网页爬取获取高清壁纸
Apr 23 Python
django 微信网页授权登陆的实现
Jul 30 Python
python游戏开发的五个案例分享
Mar 09 Python
解决Django no such table: django_session的问题
Apr 07 Python
秀!学妹看见都惊呆的Python小招数!【详细语言特性使用技巧】
Apr 27 Python
python 开心网和豆瓣日记爬取的小爬虫
May 29 #Python
Python趣味挑战之实现简易版音乐播放器
新手必备Python开发环境搭建教程
Keras多线程机制与flask多线程冲突的解决方案
May 28 #Python
pytorch 6 batch_train 批训练操作
May 28 #Python
pytorch 如何使用batch训练lstm网络
May 28 #Python
使用Pytorch训练two-head网络的操作
May 28 #Python
You might like
用PHP写的基于Memcache的Queue实现代码
2011/11/27 PHP
WordPress开发中自定义菜单的相关PHP函数使用简介
2016/01/05 PHP
为jQuery添加Webkit的触摸的方法分享
2014/02/02 Javascript
jQuery之Deferred对象详解
2014/09/04 Javascript
javascript为按钮注册回车事件(设置默认按钮)的方法
2015/05/09 Javascript
理解javascript中Map代替循环
2016/02/26 Javascript
模拟javascript中的sort排序(简单实例)
2016/08/17 Javascript
JavaScript SHA-256加密算法详细代码
2016/10/06 Javascript
微信小程序 图片边框解决方法
2017/01/16 Javascript
JavaScript实现两个select下拉框选项左移右移
2017/03/09 Javascript
详解基于webpack和vue.js搭建开发环境
2017/04/05 Javascript
nodejs实现的简单web服务器功能示例
2018/03/15 NodeJs
vue.js学习笔记之v-bind和v-on解析
2018/05/03 Javascript
在mpvue框架中使用Vant WeappUI组件库的注意事项【推进】
2019/06/09 Javascript
[03:54]DOTA2英雄梦之声_第06期_昆卡
2014/06/23 DOTA
Python实现基于HTTP文件传输实例
2014/11/08 Python
Python爬虫模拟登录带验证码网站
2016/01/22 Python
linux下安装python3和对应的pip环境教程详解
2019/07/01 Python
django多个APP的urls设置方法(views重复问题解决)
2019/07/19 Python
详解Python修复遥感影像条带的两种方式
2020/02/23 Python
将 Ubuntu 16 和 18 上的 python 升级到最新 python3.8 的方法教程
2020/03/11 Python
浅谈Python 参数与变量
2020/06/20 Python
python与js主要区别点总结
2020/09/13 Python
HTML5进阶段内联标签汇总(小篇)
2016/07/13 HTML / CSS
高级技校毕业生自荐信
2013/11/18 职场文书
信息学院毕业生自荐信范文
2014/03/04 职场文书
最美家庭活动方案
2014/08/31 职场文书
优秀高中学生评语
2014/12/30 职场文书
2015年国庆节活动总结
2015/03/23 职场文书
起诉书范文
2015/05/20 职场文书
优质护理心得体会
2016/01/22 职场文书
用基于python的appium爬取b站直播消费记录
2021/04/17 Python
超详细教你怎么升级Mysql的版本
2021/05/19 MySQL
Go语言设计模式之结构型模式
2021/06/22 Golang
详解Python为什么不用设计模式
2021/06/24 Python
一文搞懂Python Sklearn库使用
2021/08/23 Python