爬取京東商品評價信息實戰


网络爬虫

上期介紹了通過《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、運行效果

運行效果:

運行效果


作者博客:http://xiejava.ishareread.com/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章