上期介紹了通過《mitmproxy實戰-通過mitmdump爬取京東金榜數據》,能夠上京東金榜的商品一般評價都是比較好的,這次介紹如何爬取京東商品的評價信息。
一、分析商品評價的頁面信息
1、請求參數分析
京東的商品評價信息是在商品的詳情頁面,我們隨便訪問一個京東的商品詳情頁面如https://item.jd.com/100087971268.html
在這裏可以看到100087971268就是商品ID也是商品的skuId,這個是商品的唯一ID可以和很過信息關聯。我們可以通過chrome瀏覽器的調試模式來分析商品評價信息的數據是如何獲取和展示的。
通過chrome瀏覽器的調試模式可以看到,評價信息是通過https://api.m.jd.com/?appid=item-v3&functionId=pc_club_productPageComments&client=pc&clientVersion=1.0.0&t=1710122207175&loginType=3&uuid=181111935.16953916127351737253418.1695391613.1709713566.1710121957.56&productId=100087971268&score=0&sortType=5&page=0&pageSize=10&isShadowSku=0&fold=1&bbtf=&shield=
這個接口來返回的,其中關鍵的信息包括functionId=pc_club_productPageComments,productId=100087971268,page=0&pageSize=10。
productId=100087971268
表示是獲取商品ID爲100087971268的商品評價,page=0&pageSize=10
表示當前頁是0,每頁顯示10條記錄。
2、接口返回信息分析
我們可以切換到Response的標籤頁,分析接口的返回信息
在這裏可以看到通過接口反饋的是一個json格式的數據,其中評價信息就在comments的節點裏,我們只要解析這個json就可以得到具體的評價信息了。
通過參數的分析和返回結果的分析後,就可以開始編碼實現了。
二、爬取京東商品評價信息代碼實現
編碼主要實現兩個部分的內容
1、是要組織請求參數,將請求URL的一些參數用變量替換,如商品ID,當前頁等。
2、是要解析返回的JSON數據,從JSON數據中解析獲取需要的評價信息以及下載評價信息中的圖片。
在組織請求參數的時候,有兩個關鍵信息,一個是Cookie信息,一個是請求的URL,因爲訪問京東的接口要登錄,所以需要Cookie的信息。這些信息都可以在登錄到京東後在chrome瀏覽器的調試模式中可以拿到。
1、具體代碼
具體代碼如下:
getJDProdComments.py
import json
import os
import requests
from urllib.request import urlretrieve
import time
sleeptime = 1 # 休眠時間
# 瀏覽器訪問僞裝
headers = {
'cookie': '___jdu=16953916127351737253418; shshshfpa=423ebd76-fc1a-89d5-d47a-a981cedfdsf57-1686fds5177; shshshfpx=423ebd76-fc1a-89d5-d47a-a981ced31f57-1686405177; pinId=OlFK9xcJEZ3Ep3CJn7-LwLV9-x-f3wj7; pin=jd_5ab1043c91fdff; unick=xiejava; _tp=xRz2UIA0gXgQ0KtQA8IW%2BhMgOusl53MovCk%2FP0TxaIM%3D; _pst=jd_5ab1043c91bff; PCSYCityID=CN_430000_430100_0; areaId=18; ipLoc-djd=18-1482-48942-49058; b_dh=1179; b_dpr=1.100000023841858; b_webp=1; b_avif=1; autoOpenApp_downCloseDate_auto=1705396790105_1800000; b_dw=1555; __jdv=91748099|baidu|-|organic|notset|1705397493195; jsavif=1; mba_muid=16953916127351737253418; wlfstk_smdl=4d5qhwajihbur3xtxm1dghq2bwl9ebii; 3AB9D23F7A4B3C9B=ONVXQU6KOVA46KLMDJWYJ2CLCGZLCKH4NFEKT6ANBHIYQJBOWM3KHFJ3RT5NO6GKP2BQVONOJWLAKMJUMNJOAMEHJE; TrackID=1wLmzwr1GPygNiM7hoidalzvJbkLlnJRs7c_e2wlsv7h_VHaLyqnXTiW1_vIDBhlEusopAT977EO67KV2n2vMV9jMUQx8MO9jJQMMv8skxrE; thor=C1CD4973B7F47EE1FE45201B5AB2281DC485D58F5BD12AA8CEC6335A9B07F5E3F1BFD9D9DEA859A32AEDE0F33C45B55AA44327ACD87A8E174C645BE4BC987735B3DD969561D2D0AA492DD1FEC1A793AF265724B02F9850F35F0CA58E8E4A5A3C212B0734C80AD560D299EC59026506C127E953C92D271932DDDBF32BEC59091745A6CB143671358CC8A866B9A298AA865F60B9AC41AD05C6EB6781C131BD05DD; flash=2_7Kqrs87KZ1MjgKXGB8QJTs9NjTmYiJCdEV8xYwXCMezATHn-bD7kirFJuQx5ogyzo_yuQHefS-MTOx8D5rxn-5ZxA8-qMHyBfYw-1ULH1bq*; ceshi3.com=103; __jdc=181111935; token=7482844f43473090375d99ad860b4294,3,947486; __tk=mLVlrKTimJznoD3PmcVvYmZmldTlkbVaommnjmTankZOmmPDolZTZmTfSJvkYRmblDzYrLKC,3,947486; shshshsID=a8f2acdf15967d81d4c5d8b5a45b7796_1_1705476526446; 3AB9D23F7A4B3CSS=jdd03ONVXQU6KOVA46KLMDJWYJ2CLCGZLCKH4NFEKT6ANBHIYQJBOWM3KHFJ3RT5NO6GKP2BQVONOJWLAKMJUMNJOAMEHJEAAAAMNCZJJB5QAAAAAD26SPFPWINAFQMX; _gia_d=1; shshshfpb=BApXeNARaFehAyBNmDl1nYWazwPZ1Fa6NB8QBVlhW9xJ1Mt5if4S2; __jda=181111935.16953916127351737253418.1695391613.1705471486.1705476528.12; __jdb=181111935.1.16953916127351737253418|12.1705476528; joyya=1705472508.1705476529.27.0u3hno2',
'referer': 'https://item.jd.com/',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36 Edg/91.0.864.37',
}
jd_prod_pic_save_path = 'jd_prod_pic' # 圖片保存目錄
page_range = 50 # 翻50頁取500條記錄
def getJDProdComment(prod_skuId):
big_pag_path = '//img30.360buyimg.com/shaidan/s616x405_jfs/' # 評價大圖地址
tiny_pag_path = '//img30.360buyimg.com/n0/s128x96_jfs/' # 評價縮略圖地址
for i in range(page_range):
comments_url = 'https://api.m.jd.com/?appid=item-v3&functionId=pc_club_productPageComments&client=pc&clientVersion=1.0.0&t=1705853247039&loginType=3&uuid=181111935.16953916127351737253418.1695391613.1705847111.1705852812.35&productId='+str(prod_skuId)+'&score=0&sortType=5&page='+str(i)+'&pageSize=10&isShadowSku=0&fold=1&bbtf=&shield='
data = requests.get(comments_url, headers=headers)
if data:
content_data=data.content.decode('utf-8')
json_data=json.loads(content_data)
print(json_data)
if i == 0:
productCommentSummary=json_data.get('productCommentSummary')
print(prod_skuId, str(productCommentSummary))
hotCommentTagStatistics=json_data.get('hotCommentTagStatistics')
print(prod_skuId,str(hotCommentTagStatistics))
comments=json_data.get('comments')
if comments and len(comments)>0:
for comment in comments:
prod_comment_guid=comment.get('guid')
prod_comment_content=str(comment.get('content'))
prod_comment=str(comment)
images=comment.get('images')
savepath=os.path.join(jd_prod_pic_save_path,str(prod_skuId),'comments',prod_comment_guid)
if images and len(images)>0:
for image in images:
str_image_url=image.get('imgUrl').replace(tiny_pag_path, big_pag_path)
image_url='https:'+str_image_url
filename=os.path.basename(image_url)
downloadfile(image_url, savepath, filename) #下載圖片
time.sleep(sleeptime)
print(prod_comment_guid,prod_skuId,prod_comment_content,prod_comment)
time.sleep(sleeptime)
def downloadfile(downloadurl,savepath,savefilename):
savefile = os.path.join(savepath, savefilename)
try:
if not os.path.exists(savepath):
os.makedirs(savepath)
# 判斷文件是否存在,如果不存在則下載
if not os.path.isfile(savefile):
print('Downloading data from %s' % downloadurl)
urlretrieve(downloadurl, filename=savefile)
print('\nDownload finished!')
else:
print('File already exsits!')
# 獲取文件大小
filesize = os.path.getsize(savefile)
# 文件大小默認以Bytes計, 轉換爲Mb
print('File size = %.2f Mb' % (filesize / 1024 / 1024))
except Exception as e:
print('downloadfile Error:', e)
if __name__ == '__main__':
getJDProdComment('100087971268')
以上代碼中的Cookie信息,需要根據自己登錄後從chrome瀏覽器的調試模式中拿到的Cookie信息替換。
2、運行效果
運行效果: