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 相关文章推荐
rhythmbox中文名乱码问题解决方法
Sep 06 Python
关于Django外键赋值问题详解
Aug 13 Python
理解Python中的绝对路径和相对路径
Aug 30 Python
python如何拆分含有多种分隔符的字符串
Mar 20 Python
python将回车作为输入内容的实例
Jun 23 Python
Django保护敏感信息的方法示例
May 09 Python
PyQt5固定窗口大小的方法
Jun 18 Python
Python Pandas数据结构简单介绍
Jul 03 Python
Python内置类型性能分析过程实例
Jan 29 Python
Django路由层URLconf作用及原理解析
Sep 24 Python
python-图片流传输的思路及示例(url转换二维码)
Dec 21 Python
python munch库的使用解析
May 25 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
windows下apache搭建php开发环境
2015/08/27 PHP
解决PHP使用CURL发送GET请求时传递参数的问题
2019/10/11 PHP
PHP如何获取Cookie并实现模拟登录
2020/07/16 PHP
jquery 获取标签名(tagName)示例代码
2013/07/11 Javascript
使用jQuery.wechat构建微信WEB应用
2014/10/09 Javascript
实例分析javascript中的call()和apply()方法
2014/11/28 Javascript
jquery禁止回车触发表单提交
2014/12/12 Javascript
Bootstrap每天必学之折叠(Collapse)插件
2016/04/25 Javascript
jquery实现界面无刷新加载登陆注册
2016/07/30 Javascript
javascript实现将数字转成千分位的方法小结【5种方式】
2016/12/11 Javascript
详解JS中的立即执行函数
2017/02/24 Javascript
ExtJs的Ext.Ajax.request实现waitMsg等待提示效果
2017/06/14 Javascript
Vue实现一个返回顶部backToTop组件
2017/07/25 Javascript
详解vue axios二次封装
2018/07/22 Javascript
原生javascript实现连连看游戏
2019/01/03 Javascript
jQuery高级编程之js对象、json与ajax用法实例分析
2019/11/01 jQuery
详解Vue中的Props与Data细微差别
2020/03/02 Javascript
js实现经典贪吃蛇小游戏
2020/03/19 Javascript
[02:42]完美大师赛主赛事淘汰赛第三日观众采访
2017/11/25 DOTA
在Python中定义和使用抽象类的方法
2016/06/30 Python
python实现逆序输出一个数字的示例讲解
2018/06/25 Python
python输入整条数据分割存入数组的方法
2018/11/13 Python
python利用requests库模拟post请求时json的使用教程
2018/12/07 Python
python程序文件扩展名知识点详解
2020/02/27 Python
自定义实现 PyQt5 下拉复选框 ComboCheckBox的完整代码
2020/03/30 Python
pyCharm 实现关闭代码检查
2020/06/09 Python
英国蛋糕装饰用品一站式商店:Craft Company
2019/03/18 全球购物
CK澳大利亚官网:Calvin Klein澳大利亚
2020/12/12 全球购物
delegate与普通函数的区别
2014/01/22 面试题
医学院学生的自我评价分享
2013/11/19 职场文书
一年级班主任感言
2014/03/08 职场文书
幼儿园感恩节活动总结
2015/03/24 职场文书
2016年优秀团支部事迹材料
2016/02/26 职场文书
nginx反向代理时如何保持长连接
2021/03/31 Servers
Python办公自动化之Excel(中)
2021/05/24 Python
「女孩的钓鱼慢活」全新版权绘公布
2022/03/21 日漫