在爬取淘寶商品評價時,可能會被以下幾個問題所困擾:
(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 內容,大家也可以自己寫代碼自動獲取,這裏就不過多闡述了。