在爬取淘宝商品评价时,可能会被以下几个问题所困扰:
(1)直接请求,服务器要求登录帐号,怎么登录?
(2)请求到的网页 Html 怎么没有我要的评价信息?
(3)等等
下面介绍一下我使用的比较简单的获取评价的方法,可以说我在爬取过程中完全没有考虑登录的问题,那我是怎么躲开服务器犀利的“眼睛”呢?这里就要谈谈我们该如何给代码披上“外套”,靠“演技”骗过服务器了——这就是 Headers 的功劳喽!
一、明确爬取内容
注:这里说的“一次登录”,其实就是我们只需要在明确爬取内容时淘宝强制让我们登录,之后我们就不需要再考虑登录问题啦!
首先我们得明确一点,现在大多数网站都是通过异步请求的方式实现服务器与用户端的交互的,这里大家跟着我一起来感受一下:
1. 在淘宝搜 iPhone 11 ,我们就以“applestore 官方旗舰店”为例(https://detail.tmall.com/item.htm?id=602659642364&ali_refid=a3_430583_1006:1109733118:N:ZmTSOm6sbPo0QW7r3pPG9g==:8a692d17d3a85a4b089b00132a776683&ali_trackid=1_8a692d17d3a85a4b089b00132a776683&spm=a230r.1.14.1&sku_properties=1627207:28341;12304035:3222910)。
2. 打开控制台(F12),我们点击查看 Network 窗口,然后重新加载网页(Ctrl + R),我们就可以看到浏览器与服务器的各种交互文件了:
3. 接下来我们试着往下面翻浏览器,于此同时注意看右侧文件的变化,右侧会加载一些新的文件,这就是所谓的异步请求。现在我们懂了异步请求,那就来看看评论信息是什么时候加载到浏览器上的吧。
4. 等等,在此之前再来讲述一下 Network 窗口一个特别有用组件:
这个组件展示的就是随时间流逝,浏览器与服务器的交互情况,刚请求网页交互多些,线条也就多些,让浏览器静置一小会,后面的线条也就消失了,我们可以选择想查看哪个时间段的文件,这就很有利于我们找到评论文件在哪里了。
5. 现在浏览器也静置了一会了,我们来点击一下“商品详情”旁边的“累计评价”,注意到右侧控制台有变化了,那评价文件指定就在这里啦,这时候用到上面提到的组件,我们选择时间段,来缩小我们要查找的范围:
除了图片文件,从剩下的文件中我们很容易就找到评价文件了:
自然想要的文件我们找到了,接下来就是想办法批量获取啦。
二、代码编程
1. 我们来看看 Request URL :
url = 'https://rate.tmall.com/list_detail_rate.htm' \
'?itemId=602659642364' \
'&spuId=1340548940' \
'&sellerId=1917047079' \
'&order=3' \
'¤tPage=' + str(page) + \
'&append=0' \
'&content=1' \
'&tagId=' \
'&posi=' \
'&picture=' \
'&groupId=' \
'&ua=098%23E1hvM9vPvBWvUvCkvvvvvjiPn2q9gjnvR2SyzjnEPmPyQjnjnLq9gjEhP2d9gjYUdphvmpvvN9UR292ikgwCvvpvCvvvmphvLCCTqQvj7SLaifyArsa%2BD7zwa4g7EcqwaNLXrqpyCWmQD704d56OfwCl%2BboJEcqZaNsheBr1pJFUlRp4HFXXiXVvQE01Ux8x9nLIRf8tvpvIvvvv2ZCvvvvvvUUdphvU9pvv9krvpvQvvvmm86CvmmWvvUUdphvUUTyCvv9vvUvgAqoDbOyCvvOUvvhCJh9CvpvVvvpvvhCv2QhvCvvvMMGtvpvhvvvvv8wCvvpvvUmmdphvmpvUPOHjBQvI%2B86CvvyvmhymOVvp%2FpurvpvZbvkS9ow5hvEA84G3WDRtypcBRFeCvpvWzC1Gca5Nzn1wbHl4RphvCvvvvvv%3D&needFold=0' \
'&_ksTS=1582888643690_352' \
'&callback=jsonp353' \
- itemId:商品id
- sellerId:店家id
- currentPage:当前评价页,我们可以修改该参数来获取所有评价文件
- ua、_ksTS、callback:都很重要,虽然不知道他们具体的意思,但是我们得用他们“糊弄”服务器
2. 有了 Request URL 其实还不够,很重要的一点是我们要修改 user-agent ,如果我们不设置代理,后果就是 python 代码将用 python 代理请求服务器,只要服务器不傻,直接“毙”掉你的请求。在这个特定的项目中,我们还可以把 cookie 、referer 都加入到我们的 Headers 中:
3. 万事具备了,我们放代码执行:
-
comment.py
import requests
import random
from time import sleep
# 下次运行需要主动更改cookie和referer参数,内容直接复制浏览器控制台信息
Headers = {'user-agent': 'Mozilla/5.0 (X11; Linux x86_64)'
' AppleWebKit/537.36 (KHTML, like Gecko)'
' Chrome/80.0.3987.106 Safari/537.36',
'cookie': 'cna=gSYsFs5GqgcCAXLV/PLN3yGH;'
' hng=CN%7Czh-CN%7CCNY%7C156;'
' lid=ambitioner%E4%B8%B6;'
' enc=L9HQuV5GHNRsGeq9rZ3xafuSSX2F46GZYB4B2JCyacx3KPhqjHSF%2FRo%2Bw0y9Jx6i4DQECoE%2BjkAgHqXEFzKm1A%3D%3D;'
' _m_h5_tk=29d764e2058930bfd11ab05d80a3cb86_1582804356322;'
' _m_h5_tk_enc=9fb28a8f39883bf19bac2ddcb7ac12d0;'
' sgcookie=DGRVAmM8cBxFOvUJDfVh%2B;'
' uc1=cookie14=UoTUOLRwaXjqcg%3D%3D;'
' t=7458db744d83ab1d06ee636f30708330;'
' uc3=lg2=UIHiLt3xD8xYTw%3D%3D&nk2=Any3BqBNXeXE67%2BP&vt3=F8dBxd3yPWVaWUFtXLY%3D&id2=UUGjMVyuhEU30A%3D%3D;'
' tracknick=ambitioner%5Cu4E36;'
' uc4=nk4=0%40AJc9Jh4DCme1Xd6KuxQkwbBbdrKdGxI%3D&id4=0%40U2OU%2FjjOW%2Bci6bsS%2BHdj1aRVz0Ys;'
' lgc=ambitioner%5Cu4E36;'
' _tb_token_=7e7e5b3b03377;'
' cookie2=145734a209d5cb9239724be258b59208;'
' x5sec=7b22726174656d616e616765723b32223a226266393232346466353634623961343735323239356464663533346366383730434b574c332f4946454a4c796e4d624b2f367a3357673d3d227d;'
' l=dBIU44EgqnlwebYUBOfwZDQk4QQTWdAXCsPr98cToIB1O56Z7dWpxHwEaNbBT3QQEt5AYeKzK6zxJRUp78ULyx_ceTwhKXIpBUJB8e1..;'
' isg=BGRkyc3t5o_MVRGxU2Qu_OUoNWtW_YhnaPBDsH6JiyplKQnzpw7b9yjP7YEx8cC_',
'referer': 'https://detail.tmall.com/item.htm'
'?id=602858459541&ali_refid=a3_430583_1006:1103534738:N:FcbnhkUVpVThyuKFufQFZg==:2de1d8285a37a32169146d902490766b'
'&ali_trackid=1_2de1d8285a37a32169146d902490766b&spm=a230r.1.14.1'
'&sku_properties=10004:709990523;5919063:6536025'}
def get_comment(page):
# 下次运行需要主动更改ua、_ksTS和callback参数,内容直接复制浏览器控制台信息
url = 'https://rate.tmall.com/list_detail_rate.htm' \
'?itemId=602858459541' \
'&spuId=1340548940' \
'&sellerId=713805254' \
'&order=3' \
'¤tPage=' + str(page) + \
'&append=0' \
'&content=1' \
'&tagId=' \
'&posi=' \
'&picture=' \
'&groupId=' \
'&ua=098%23E1hvEpvxv7OvUvCkvvvvvjiPn2q9sjE2PLMUtj3mPmPpljnhPLsOQjYnn2SWAjlHRphvCvvvvvmCvpvZz2saf4dNznQGDFnfYMdwFYAC7IVrvpvEvvFQvT0rvPFrdphvmpvWvUnMNQvIsu6Cvvyv2mh2HBZvUnJ5vpvhvvmv9FyCvvpvvvvv2QhvCvvvMMGEvpCWvVtSvvwTD7zOaXZBWD0U%2BExrVTtYVVzOa4QBnk19kbmxfBKKNB3r0j7%2BhfUeCbmDYE7rV16kARLUTE9XaDdXS47BhC3qVUcnDOvfjfyCvm9vvvvnphvvvvvv9krvpvkCvvmm86Cv2vvvvUUdphvUUQvv9krvpv9FkphvC99vvpHgo8yCvv9vvUvgAHkORphCvvOvCvvvphmjvpvhvvpvv86CvCh92U0mNc6vaCOidAI3pQeHA46CvvyvCPKmiTwvNCVrvpvEvvFl9sWsvUAEdphvmpvWgQnI4vmGH46CvvyvCb821wZvpBArvpvEvvkC96lnvh77dphvmpvhoUWcHQmudv%3D%3D&needFold=0' \
'&_ksTS=1582839364887_2210' \
'&callback=jsonp2211' \
html = requests.get(url, headers=Headers)
html = html.text
return html
def doc_write(page, html):
# 需要在python同级目录创建data文件夹
pathname = '../data/' + str(page) + '.html'
with open(pathname, 'w', encoding='utf-8') as f:
f.write(html)
if __name__ == '__main__':
my_page = 1
while True:
sleep(random.randint(2, 6))
my_html = get_comment(my_page)
if 'rateDetail' in str(my_html):
doc_write(my_page, my_html)
print('%s has finished.' % my_page)
my_page += 1
else:
print('Error.')
break
- read_comment_file.py
import json
import re
def read(pathname):
with open(pathname, 'r') as f:
html = f.readlines()[1]
html_dict = json.loads(re.findall(r'jsonp\d+\((.+?})\)', html)[0])
return html_dict
def analysis(html_dict):
# 评价
for j in html_dict['rateDetail']['rateList']:
print(j['rateContent'])
if __name__ == '__main__':
my_page = 1
my_pathname = '../data/' + str(my_page) + '.html'
# 获取html_dict
my_html_dict = read(my_pathname)
# 解析html_dict
analysis(my_html_dict)
代码已上传到本人 GitHub :https://github.com/Ambitioner-c/taobao_comment.git
注:每次执行需手动修改 Headers 内容,大家也可以自己写代码自动获取,这里就不过多阐述了。