爬取JD商品评论并数据可视化
这篇文章介绍了如何通过抓取JSON数据来爬取京东评论,避免了传统方法的复杂操作。文章提供了完整的代码示例,并详细说明了数据处理、词云生成和图表制作的过程。
本文参考了知乎文章 https://zhuanlan.zhihu.com/p/60444767
思路
通过提取JSON数据的方式,可以直接获取评论信息,无需逐一获取页面标签等复杂数据,简化了数据获取流程(操作简便)。
requirements
requests
pyecharts
pandas
jieba
wordcloud
matplotlib
爬取评论
先贴代码
# -*- coding:utf-8 -*-
import requests
url = 'https://sclub.jd.com/comment/productPageComments.action?productId=100004325476&score=0&sortType=5&page=0&pageSize=10&isShadowSku=0&fold=1'
# 请求头
headers = {
'Connection': 'Keep-Alive',
'Accept': 'text/html, application/xhtml+xml, */*',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/74.0.3729.169 Safari/537.36',
'Referer': 'https://item.jd.com/100004325476.html',
'Host': 'sclub.jd.com'
}
def get_comment(url):
# 请求
req = requests.get(url, headers=headers)
# 数据处理
res = req.json() # 转换成python对象
comments = res['comments']
total = []
for comment in comments:
data = {
'id': comment['id'],
'content': comment['content'],
'score': comment['score'],
'userLevelName': comment['userLevelName'],
'userClientShow': comment['userClientShow'],
'mobileVersion': comment['mobileVersion']
}
total.append(data)
return total
if __name__ == '__main__':
res = get_comment(url)
print(res)
在处理请求头时,需要注意一些特殊情况。如果采用默认的请求头设置,如'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36',可能会遇到一些不理想的数据返回。可以通过浏览器开发者工具来查看具体的请求头信息(不建议详细讲解,可以参考相关资源),然后将其中的请求头部分复制到代码中进行处理。
爬取并存储
还是先贴代码
# -*- coding:utf-8 -*-
import get_page_comment as cm
import store_comment as st
import time
import random
# 构造url
urls = []
for score in range(1, 4, 1):
for page in range(0, 10, 1):
ori = "https://sclub.jd.com/comment/productPageComments.action?productId=100004325476&score=%(score)d&sortType=5&page=%(page)d&pageSize=10&isShadowSku=0&fold=1" % {
'score': score, 'page': page}
urls.append(ori)
# print(urls)
# 获取评论
res = []
for url in urls:
s = cm.get_comment(url)
res += s
print(s)
time.sleep(random.uniform(1, 3))
# print(res)
# 存储
st.store_data(res)
这里url的构造需要用到两个变量,灵机一动想到了用格式化字符串的方式来构造,这样写出来的代码更Pythonic了。需要注意的是,为了防止被反爬,需要加入随机的sleep行为。复习一下,使用Selenium无需反爬,非常方便。
jieba分词和词云
然后就是用jieba分词做词云了
贴下代码
# -*- coding:utf-8 -*-
import pandas as pd
import jieba
from wordcloud import WordCloud
import matplotlib.pyplot as plt
# 从xls读入数据
data = pd.read_excel('JD.xls')
comments = data['content']
text = ''
for comment in comments:
text += ' '.join(jieba.cut(comment))
wordcloud = WordCloud(
font_path="C:/Windows/Fonts/msyh.ttc",
background_color="white",
width=1000,
height=880,
stopwords={'耳机', '京东', '非常'}
).generate(text)
plt.imshow(wordcloud, interpolation="bilinear")
plt.axis("off")
plt.show()
在另一篇博客中,我提供了关于具体用法的详细说明。 <>
得到的词云:

pyecharts得到图表
同样先贴一下代码
# -*- coding:utf-8 -*-
import pandas as pd
from pyecharts.charts import Bar
# 从xls读入数据
data = pd.read_excel('JD.xls')
userLevelName = data['userLevelName']
count = userLevelName.value_counts() # 对各项计数
num = count.tolist() # 转换成python对象
bar = (Bar()
.add_xaxis(['PLUS会员', '金牌会员', '银牌会员', '钻石会员', '铜牌会员', '注册会员'])
.add_yaxis('数量',yaxis_data=num))
bar.render('a.html')
整个操作流程较为简便,且步骤清晰。具体而言,首先通过pandas库导入数据,完成数据的读取操作。随后,对指定字段进行统计分析,获取相关数据特征。接着,将其转换为列表形式,便于后续处理。最后,以柱状图展示结果,直观呈现数据分布情况。
得到的结果:

总结
整个过程相对来说不算太难,主要得益于之前的知识储备。其中,直接抓取返回的JSON数据是一个非常有意思的点。JSON数据结构清晰,便于获取和处理,特别适合动态网站的场景,是一个不错的选择。
