京东商品评论爬虫

96
_hahaha
0.1 2017.06.08 08:18* 字数 4567

抓取京东商城商品评论信息,并对这些评论信息进行分析和可视化。下面是要抓取的商品信息,一款女士文胸。这个商品共有红色,黑色和肤色和砖红四种颜色, 70B到90D共18个尺寸,以及1100+条购买评论。

京东商品评论信息是由JS动态加载的,所以直接抓取商品详情页的URL并不能获得商品评论的信息。因此我们需要先找到存放商品评论信息的文件。这里我们使用Chrome浏览器里的开发者工具进行查找。

按快捷键F12,在弹出的开发者工具界面中选择Network,设置为只查看JS文件。然后刷新页面。页面加载完成后向下滚动鼠标找到商品评价部分,等商品评价信息显示出来后,在下面Network界面的左侧筛选框中输入productPageComments,这时下面的加载记录中只有一条信息,这里包含的就是商品详情页的商品评论信息。点击这条信息,在右侧的Preview界面中可以看到其中包含了当前页面中的评论信息复制这条信息,并把URL地址放在浏览器中打开,里面包含了当前页的商品评论信息。这就是我们要抓取的URL地址'https://sclub.jd.com/comment/productPageComments.action?callback=fetchJSON_comment98vv90&productId=10001229490&score=0&sortType=5&page=0&pageSize=10&isShadowSku=0&fold=1'

仔细观察这条URL地址可以发现,其中productId=10001229490是当前商品的商品ID。与商品详情页URL('https://item.jd.com/10001229490.html')中的ID一致。而page=0是页码。如果我们要获取这个商品的所有评论,只需要更改page后面的数字即可。其中中‘callback=fetchJSON_comment98vv90’和‘isShadowSku=0&fold=1’,经测试,是可以删除的,这样可以简化url,不至于看起来那么长。

在获得了商品评论的真实地址以及URL地址的规律后,我们开始使用python抓取这件商品的1100+条评论信息,并对这些信息进行处理和分析。

开始前的准备工作

在开始抓取之前先要导入各种库文件,这里我们分别介绍下需要导入的每个库文件的名称以及在数据抓取和分析中的作用。requests用于进行页面抓取,time用于设置抓取过程中的Sleep时间,random用于生产随机数,这里的作用是将抓取页面的顺序打乱,re用于在抓取后的页面代码中提取需要的信息,numpy用于常规的指标计算,pandas用于进行数据汇总和透视分析,matplotlib用于绘制各站图表,jieba用于对评论内容进行分词和关键词提取。

将爬虫伪装成浏览器

导入完库文件后,还不能直接进行抓取,因为这样很容易被封。我们还需要对爬虫进行伪装,是爬虫看起来更像是来自浏览器的访问。这里主要工作是设置请求中的头文件信息

头文件信息很容易找到,在Chrome的开发者工具中选择Network,刷新页面后选择Headers就可以看到本次访问的头文件信息,里面包含了一些浏览器的技术参数和引荐来源信息。将这些信息直接添加到代码中就可以,这里我们将头部信息保存在headers中。

1.  #设置请求中头文件的信息

headers={'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36'}

抓取商品评论信息

设置完请求的头文件信息后,我们开始抓取京东商品评论的信息。前面分析URL的时候说过,URL中包含两个重要的信息,一个是商品ID,另一个是页码。这里我们只抓取一个商品的评论信息,因此商品ID不需要更改。但这个商品的评论有1100+条,也就是有近100页需要抓取,因此页码不是一个固定值,需要在0-100之间变化。这里我们将URL分成两部分,通过随机生成页码然后拼接URL的方式进行抓取。

2.  #设置URL的第一部分

url1 = 'https://sclub.jd.com/comment/productPageComments.action?callback=fetchJSON_comment98vv90&productId=10001229490&score=0&sortType=5&page='

#设置URL的第二部分

url2 = '&pageSize=10&isShadowSku=0&fold=1'

3.  #计算商品评论页面总数

这里根据爬去的html长度判断是否最后一页,不具备合理性,也不具备可移植性,换成其它商品页面就不可行了。(京东商品评论最多显示100页,不知道有没有其它办法可以爬取更多)

运行结果如下:

所以抓取范围定位从0-69页。

下面是具体的抓取过程,使用for循环每次从0-69的数中找一个生成页码编号,与两部分的URL进行拼接。生成要抓取的URL地址并与前面设置好的头文件信息发送请求获取页面信息。将获取到的页面信息进行汇总。每次请求间休息2秒钟,避免过于频繁的请求导致返回空值。

4.  #拼接URL并乱序循环抓取页面

在抓取的过程中输入每一步抓取的页面URL以及状态。通过下面的截图可以看到,在page参数后面的页码是随机生成的并不连续。


抓取完页面后,我们还需要对页面进行编码。完成编码后就可以看到其中所包含的中文评论信息了。后面大部分苦逼的工作就是要对这些评论信息进行不断提取和反复的清洗。

5#对抓取的页面进行编码

comment_content = str(comment_content, encoding="GBK")

这里建议将抓取完的数据存储在本地,后续工作可以直接从本地打开文件进行清洗和分析工作。避免每次都要重新抓取数据。这里我们将数据保存在当前文件夹中的comment.txt文件中。

6#将编码后的页面输出为txt文本存储

f=open('comment.txt','w')

f.write(comment_content)

f.close()

读取文件也比较简单,直接open加read函数就可以完成了。

7#读取存储的txt文本文件

f=open('comment.txt','r')

html=f.read()

f.close()

提取信息并进行数据清洗

京东的商品评论中包含了很多有用的信息,我们需要将这些信息从页面代码中提取出来,整理成数据表以便进行后续的分析工作。这里应该就是整个过程中最苦逼的数据提取和清洗工作了。我们使用正则对每个字段进行提取。对于特殊的字段在通过替换等方式进行提取和清洗。

下面是提取的第一个字段userClient,也就是用户发布评论时所使用的设备类型等字段

还有一些字段比较负责,无法通过正则一次提取出来,比如isMobile字段,有些值的后面还有大括号。这就需要进一步的提取和清洗工作。

1 #使用正则提取isMobile字段信息

使用for循环配合替换功能将字段中所有的}替换为空。替换完成后字段看起来干净多了。

2 #使用正则提取productSize字段信息

productSize字段中包含了胸围和杯罩两类信息,为了获得独立的杯罩信息需要进行二次提取,将杯罩信息单独保存出来。

3 #使用正则提取时间字段信息

日期和时间信息处于前20个字符,在二次提取中根据这个规律直接提起每个条目的前20个字符即可。将日期和时间单独保存为creationTime。在上一步日期和时间的基础上,我们再进一步提取出单独的小时信息,方法与前面类似,提取日期时间中的第11和12个字符,就是小时的信息。提取完保存在hour字段以便后续的分析和汇总工作。

4 #对提取的评论信息进行去重

最后要提取的是评论内容信息,页面代码中包含图片的评论信息是重复的,因此在使用正则提取完后还需要对评论信息进行去重。使用if进行判断,排除掉所有包含图片的评论信息,已达到评论去重的目的。

完成所有字段信息的提取和清洗后,将这些字段组合在一起生成京东商品评论数据汇总表。下面是创建数据表的代码。数据表生成后还不能马上使用,需要对字段进行格式设置,例如时间和日期字段和一些包含数值的字段。具体的字段和格式设置依据后续的分析过程和目的。这里我们将creationTime设置为时间格式,并设置为数据表的索引列。将days字段设置为数值格式。

5#将前面提取的各字段信息汇总为table数据表,以便后面分析


6#保存table数据表

table.to_csv('jd_table.csv')

数据分析及可视化

1. 分月评论数据变化趋势

首先查看京东商品评论的时间变化趋势情况,大部分用户在购买商品后会在10天以内进行评论,因此我们可以近似的认为在一个月的时间维度中评论时间的变化趋势代表了用户购买商品的变化趋势。

按月的维度对数据表进行汇总,并提取每个月的nickname的数量。下面是具体的代码和分月数据

数据范围从2015年11月到2017年4月。使用柱状图对分月数据进行可视化。从图表中可以看到2016年6月是评论的高峰,也可以近似的认为这个时间段是用户购买该商品的高峰(6月18日是京东店庆日)。排除2016年6月和不完整的11月数据,整齐趋势中冬季评论量较低,夏季较高。这是由于该商品的季节属性导致的,超薄胸罩更适合夏天佩戴(这个属性我们是在用户的评论中发现的,在京东的商品介绍中并不明显,只在标题中以”薄杯”说明)。

2. PC和移动端使用情况

通过筛选将数据表分为使用移动设备和未使用移动设备两个表格,再分别查看和对比评论变化趋势。

从结果中可以看出使用移动设备进行评论的用户在所有的时间段中都要明显高于使用PC的用户。

3. 24小时评论评论变化趋势

按小时维度对评论数据进行汇总,查看用户在24小时中的评论变化趋势。这里需要说明的是24小时趋势只能反映用户登录京东商城的趋势,并不能近似推断用户购买商品的时间趋势

从24小时评论趋势图来看,发布商品评论的趋势与作息时间一致,并且每日的闲暇时间是发布评论的高峰。如早上的8点,中午的12点和晚上的22点,是一天24小时中的三个评论高峰点。

将24小时的评论数量分为移动设备和未使用移动设备,查看并对比这两者的变化趋势情况。

移动设备的评论数量在24小时中的各个时间段都要高于PC的评论数量,并且在晚间更加活跃,持续时间高于PC端。这里我们产生了一个疑问,在一天中的工作时间段中,大部分用户都会在电脑旁,但为什么这些时间段里移动设备的评论数量也要高于PC端呢?这是否与胸罩这个产品的私密性有关联。用户不希望别人看到自己购买的商品或评论的内容,所以选择使用移动设备进行评论?

4. 用户客户端分布情况

前面的分析中,我们看到使用移动设备进行评论的用户要远高于PC端的用户,下面我们对用户所使用的设备分布情况进行统计。首先在数据表中按用户设备(userClient)对nickname字段进行计数汇总

从用户客户端分布情况来看,移动端的设备占大多数,其中使用移动端的用户要高于Android用户。由于微信购物和QQ购物单独被分了出来,无法确定设备,因此单独进行对比。使用微信购物渠道的用户要高于QQ购物


5. 购买后评论天数分布

在购买后评论天数方面,我们将用户发布评论与购买的时间间隔分为7组,分别为购买后1-5天内,5-10天内,10-15天内,15-20天内,20-25天内,25-30天内,以及大于30天。然后统计并对比用户在不同时间区间内发布评论的数量情况。

从图表中看出,购买后5天以内是用户发布评论的高峰,也就我们之前推测评论时间趋势近似于购买时间的依据。随着时间的增加评论数量逐渐下降。


6. 胸罩颜色偏好分布

这款胸罩共分为三个颜色,红色,肤色,黑色和砖红色。我们按颜色对评论数据进行汇总,查看用户对不同胸罩颜色的偏好情况

从不同颜色的评论数量上来看,大部分用户购买的是砖红色和红色,购买黑色的用户数量最少

8. D&E cup用户城市分布情况

最后我们再看看下D杯罩和E杯罩用户的城市分布情况,在数据表中并不是所有的评论都有城市信息。因此按城市统计出来的数据可能并不准确,仅供参考。

首先从数据表中筛选出cup值为D和E的数据,并保存在新的数据表中。

在新的数据表中按用户所在城市(userProvince)进行汇总。查看不同城市D和E杯罩的数量。

将汇总结果绘制为图表,从图表来看,数量最多的为未知城市,排除未知城市,北京和广东的数量遥遥领先,其次为四川和上海。

胸罩评论内容语义分析

文章最后我们对商品的评论内容进行语义分析,看看大家在评论中都在说些什么

好好先生购买比例

在人工查看了一些评论内容后,我们发现一些有意思的信息。有一部分评论是老公或男朋友发的,这说明一些好好先生会帮老婆或女友购买胸罩。那么这部分用户的比例有多少呢?

我们把评论中包含有关键词“老婆”和“女朋友”的评论单独保存在出来

查看这些包含关键词的评论内容,确实是老公和男朋友来购买胸罩并且发布的评论

经过计算,在这款胸罩产品的评论中,由老公或男朋友购买的比例仅为2.35%。

商品评论关键词分析

回归到商品评论分析,我们使用结巴分词对所有胸罩的评论信息进行了分词,并提取了权重最高的关键词列表。

从高权重关键词列表来看,用户评论以正面信息为主,”不错”,”舒服”,”喜欢”等主观感受的正面评论权重较高

结语

由于抓取的数量少,结果仅供参考。当评论页数较多式可以采用多线程爬虫爬取商城评论,通过引用from multiprocessing.dummy importPool as ThreadPool,本代码中,url_manager这个类在另外一个.py文件中,用于爬去所有页面url,并返回url集合,这里我就不做展示了。还有一点是我使用的是python3.6版本,和python2.7在一些语法上的差别。

代码如下:

参考

蓝鲸网站分析博客

数据分析
Web note ad 1