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文件的md5加密方法
Apr 06 Python
python实现机器人行走效果
Jan 29 Python
python实现多线程网页下载器
Apr 15 Python
python脚本生成caffe train_list.txt的方法
Apr 27 Python
Python 中的range(),以及列表切片方法
Jul 02 Python
python 判断参数为Nonetype类型或空的实例
Oct 30 Python
基于Python的PIL库学习详解
May 10 Python
在Django model中设置多个字段联合唯一约束的实例
Jul 17 Python
Django+uni-app实现数据通信中的请求跨域的示例代码
Oct 12 Python
解决Jupyter无法导入已安装的 module问题
Apr 17 Python
Python模拟登入的N种方式(建议收藏)
May 31 Python
通过实例解析Python RPC实现原理及方法
Jul 07 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 截取字符串 分别适合GB2312和UTF8编码情况
2009/02/12 PHP
简单实现限定phpmyadmin访问ip的方法
2013/03/05 PHP
自己写的php curl库实现整站克隆功能
2015/02/12 PHP
PHP如何通过表单直接提交大文件详解
2019/01/08 PHP
PHP Laravel中的Trait使用方法
2019/01/20 PHP
Laravel登录失败次数限制的实现方法
2020/08/26 PHP
把textarea中字符串里含有的回车换行替换成<br>的javascript代码
2007/04/20 Javascript
用js解决数字不能换行问题
2010/08/10 Javascript
jQuery分别获取选中的复选框值的示例
2014/06/17 Javascript
JS实现仿QQ聊天窗口抖动特效
2015/05/10 Javascript
javascript无刷新评论实现方法
2015/05/13 Javascript
Ajax清除浏览器js、css、图片缓存的方法
2015/08/06 Javascript
JavaScript中获取Radio被选中的值
2015/11/11 Javascript
gulp-htmlmin压缩html的gulp插件实例代码
2016/06/06 Javascript
JS 组件系列之Bootstrap Table的冻结列功能彻底解决高度问题
2017/06/30 Javascript
webpack中使用iconfont字体图标的方法
2018/02/22 Javascript
详解Vue源码学习之callHook钩子函数
2018/07/25 Javascript
解决vue脚手架项目打包后路由视图不显示的问题
2018/09/20 Javascript
vue实现pdf导出解决生成canvas模糊等问题(推荐)
2018/10/18 Javascript
vue中引入第三方字体文件的方法示例
2018/12/17 Javascript
python使用urllib2提交http post请求的方法
2015/05/26 Python
python使用psutil模块获取系统状态
2016/08/27 Python
Python实现的括号匹配判断功能示例
2018/08/25 Python
django ManyToManyField多对多关系的实例详解
2019/08/09 Python
python元组和字典的内建函数实例详解
2019/10/22 Python
python实现简单颜色识别程序
2020/02/19 Python
python实现用户名密码校验
2020/03/18 Python
html5的自定义data-*属性与jquery的data()方法的使用
2014/07/02 HTML / CSS
英国手工制作的现代与经典的沙发和床:Love Your Home
2020/09/26 全球购物
什么是反射?如何实现反射?
2016/07/25 面试题
高中生学习生活的自我评价
2013/10/09 职场文书
孝老爱亲模范事迹
2014/01/24 职场文书
遗嘱继承公证书
2014/04/09 职场文书
房地产资料员岗位职责
2014/07/02 职场文书
2015年环境监察工作总结
2015/07/23 职场文书
python manim实现排序算法动画示例
2022/08/14 Python