上一篇使用Java写了数据爬虫用以抓取京东商品名称,但实际上京东上有很多有价值的数据,其中之一就是用户反馈即评论。今天就用Python写一个小爬虫把它抓出来。
Python抓取京东商品评论
工程开始
与一般的网页数据不同,这里我们打开网页控制台,找到Network——JS——productPageComm… 看右边Preview中的数据,发现我们想要的数据就在这个数据包里。
找到了数据包,我们还需要知道它的请求头也就是Headers,这里面有一些很重要的请求参数,我们在下面这两张图中的到数据包的URL,cookie,referer,user-agent等请求参数
其中最下方的一些参数是数据的一些详细参数,需要留下来有用
执行工程
找到了数据和这些参数,我们就可以开始这项工程了。因为这里的评论采用的的Json数据格式,因此我们要用到Json解析这个数据包。多说不易,现在就开始实现。
程序演示:
import requests
import json
import re
import time
# 获取网页html
def getHTML(url, data, head):
# 捕获异常
try:
r = requests.get(url, params=data,headers=head)
r.raise_for_status()
return r.text
except:
print('爬取失败')
# 获取某一页评论数据
def getComment(html):
# 页面编成json数据,无论什么格式的数据编码后都变成字符串类型
i = json.dumps(html)
# json转Python对象
j = json.loads(i)
# 正则表达式数据过滤
comment = re.findall(r'{"productAttr":.*}', j)
# json解析
comm_dict = json.loads(comment[0])
# 存数据实体
commentList = []
# comments是评论实体
comm_list = comm_dict['comments']
for com in comm_list:
# 用户id
id=com['id']
# 名称
name=com['referenceName']
# 用split去空格与换行 join连成整段评论
comment = ''.join(com['content'].split())
# 用户评分
score = com['score'] # 用户打分
# 时间
time=com['creationTime']
# 放入列表
commentList.append([id,name,score, comment])
return commentList
# 分页获取商品评论
def getComments(url, num):
head={
"cookie": "__jdu=514410137; shshshfpa=de1af04d-d6e2-d3f8-66c0-f7d724ece5b4-1563464689; shshshfpb=n9hljtB4BtrvID18wW3hGEA%3D%3D; user-key=90547600-3f76-4b35-82c5-769e44d366bb; PCSYCityID=CN_410000_411600_411681; cn=1; unpl=V2_ZzNtbRdVEEElD0Bcfh5ZUWILRQoRV0BBIAsUUisbDlVkBxYKclRCFX0UR1JnGlUUZwQZXUpcRhNFCEdkeBBVAWMDE1VGZxBFLV0CFSNGF1wjU00zQwBBQHcJFF0uSgwDYgcaDhFTQEJ2XBVQL0oMDDdRFAhyZ0AVRQhHZH8ZWQBnAhJfRGdzEkU4dlx%2fGlUGYzMTbUNnAUEpCkRSfR9ZSGMDF1hCVkMXczhHZHg%3d; __jdv=76161171|baidu-pinzhuan|t_288551095_baidupinzhuan|cpc|0f3d30c8dba7459bb52f2eb5eba8ac7d_0_d3bea679464e49ffb12ed2c7a3ca255f|1564301987290; __jda=122270672.514410137.1563429557.1564131246.1564301987.18; __jdc=122270672; areaId=7; 3AB9D23F7A4B3C9B=YVDJT5SQG7K264X7SHL45HEDVKQ3JTSIIK2MSSYK4HSLG7INEVZFJWERJLMER2KDKZ6HMD357AE5XIGS6PPWOJB7GU; shshshfp=8fb64f0a1c8c89bc0df6660ba541fff5; ipLoc-djd=7-527-536-34975; JSESSIONID=F95037CB7B4578CA78FCF406F4FD084E.s1; shshshsID=50f3460c5eb2ffe9a0f9b54fcf341eff_12_1564304160657; __jdb=122270672.12.514410137|18.1564301987"
,"referer": "https://item.jd.com/100003786269.html"
,"user-agent": "Mozilla/5.0"
}
data={
"callback":"fetchJSON_comment98vv5459",
"productId":"100003786269",
"score": 0,
"sortType": 5,
"page": 0,
"pageSize": 10,
"isShadowSku": 0,
"fold": 1
}
# 数据容器
commetns=[]
for i in range (num+1):
try:
# 控制页码
data['page']=i
html=getHTML(url,data,head)
commlist = getComment(html)
# 捕获异常
except:
print("第%d页抓取失败"%i)
commetns.append(commlist)
print("第%d页评论抓取成功!"%i)
# 睡眠一会防止被封
time.sleep(3)
return commetns
def main():
# 评论根网页
url="https://sclub.jd.com/comment/productPageComments.action?"
num=(int)(input("请输入抓取结束页码:"))
commlist=getComments(url,num)
print("数据抓取结束,准备写入文件中。。。")
page=0
f = open('JDComment.txt', 'a', encoding='UTF-8')
for list in commlist:
print("--->第%d页正在写入。。。"%page)
strpage="--->第"+str(page)+"页共计"+str(len(list))+"条评论如下:"
f.write(strpage+'\n')
# 睡一会防止写入出错
time.sleep(1.5)
for data in list:
strid="用户ID:"+str(data[0])
f.write(strid+'\n')
strname=" 产品:"+str(data[1])
f.write(strname+'\n')
strsc=" 评分:"+str(data[2])
f.write(strsc+'\n')
strcom=" 评论详情:"+str(data[3])
f.write(strcom+'\n')
print("第%d页写入成功"%page)
page+=1
# 关闭文件
f.close()
main()
程序结束。
校验结果:
这里我们只抓取了5页评论数据,检查运行结果和文件后发现,前5页评论数据全部抓取成功!
若非群玉山头见,会向瑶台月下逢。