Python爬蟲二:抓取京東商品列表頁面資訊
環境:Windows7+python3.6+Pycharm2017
目標:抓取京東商品列表頁面資訊:售價、評論數、商品名稱-----以手機為例
---全部文章: 京東爬蟲 、鏈家爬蟲、美團爬蟲、微信公眾號爬蟲、字型反爬、Django筆記、阿里雲部署、vi\vim入門----
開啟京東首頁,搜尋框輸入‘手機’搜尋,顯示結果如下圖。搜尋結果顯示一共有100頁,每頁有60條商品資訊,抓取每件商品的售價、名稱、評價數量。抓取這100頁資料存入csv檔案中。
一、思路分析
首先每一頁有60條商品資訊,但是當你開啟網頁的時候會發現,每次只載入前面30條資訊,後面的30條資訊在你下拉瀏覽的時候才會載入,如下圖。也就是說後30條資訊是動態載入的,於是我們認為每一頁的資訊可以分為前30條和後30條分開抓取。
前30條資訊的抓取: 第一頁的url如下,直接用requests.get 請求就能得到前30條商品資訊。
後30條資訊的抓取:既然這30條資訊是動態載入,我們希望找到對應的API介面,然後構造請求來模擬瀏覽器。右鍵檢查開啟Chrome瀏覽器的開發者模式,點選Network,選擇 XHR型別,下拉京東頁面,可以發現抓取到兩條請求。點選第一條,單擊右邊的Response項可以發現返回的是一串HTML程式碼,其中就包含著我們想要的後30條手機的資訊。
點選Headers,找到請求的url地址,請求的header資訊,是一個get請求,如上圖。
翻頁的實現:
我們已經知道了每一頁的商品資訊如何抓取,接下來如何翻頁是我們要考慮的問題。一般get請求實現翻頁都是url中有一個對應的Page引數,通過改變這個引數來定位不同頁面。我們多翻幾頁,來看下url的變換規律。如下圖,url中一共包含兩個變化的引數,一個是page,一個是s。page引數很容易發現就是當前頁數n*2-1,至於這個s引數,也是一種累加的關係,但是每次增加的值不是固定的,尤其是前面幾頁。後面再討論。
至於後30條資訊的url的變化規律,我們先看下這個網址,很長。首先url尾部的一串數字共30個,很容易想到是當頁前30條商品的ID,實際傳送請求時去掉也不影響。還有tpl=3也可以去掉,不影響。
https://search.jd.com/s_new.php?keyword=%E6%89%8B%E6%9C%BA&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&cid2=653&cid3=655&page=8&s=204&scrolling=y&log_id=1530006198.15672&tpl=3_M&show_items=1058633586,15610845215,6176077,5361711,16840903541,27141647261,5934357,28505252057,5424574,6610412,7930067,28769336369,5019352,22225587075,27865526962,11378358411,3901175,26642320667,7643011,28410642805,28756072324,11792731652,26188176454,11077796654,5716981,7438300,26817351676,6069862,21759433312,25863368410
最後url精簡到:
https://search.jd.com/s_new.php?keyword=%E6%89%8B%E6%9C%BA&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&cid2=653&cid3=655&page=8&s=204&scrolling=y&log_id=1530006198.15672
觀察後發現url包含三個變化的引數,page,s,還有log_id ,跟上面相比多了一個log_id。這個引數其實就是Unix時間戳,表示當前的時間,直接呼叫time函式就可以得到。page就是當前頁數n*2 。關於這個s引數,這兩個url的s引數每次增加的並不是固定值,你多試幾次發現每次都會不一樣,包括第一頁的s值。大概就是每次增加50+,這個s不同,我覺得就像代表不同的排列順序。因為這個你搜尋‘手機’,其實過一段時間這個出來結果就會有些變化。誰排前面,誰排後面。還有就是一頁60條商品中其實有一些是廣告,如下圖紅米6右下角。還有價格動態載入的商品,同下圖的小米MIX2,你點選方框裡的小圖,價格會跟著切換。這兩類商品和其他的商品在html的標籤中還有一些不一樣,抓取的時候要考慮到。我覺得就是這兩類商品是隨時在網頁顯示中會變動的。s增加52 的意思是不是獲取52條普通商品資訊,再在其中插入8條廣告類的資訊,拼成一頁。最後我在實際抓取的時候索性把第一個url中的s引數去掉,在觀察翻頁後每次動態請求的url中的s引數大概是增加48,每次就增加48來抓取。
二、程式碼實現
京東還算是對爬蟲比較友好的,不用代理直接抓取100頁也沒有出現反爬措施。請求庫用的requests,解析網頁用的xpath。直接複製瀏覽器中的header資訊,用requests傳送get請求,對於返回的html程式碼用xpath進行解析。前30條信心,和後30條資訊解析的方式是一樣的。完整程式碼如下:
import requests
from lxml import etree
import time
import csv
#定義函式抓取每頁前30條商品資訊
def crow_first(n):
#構造每一頁的url變化
url='https://search.jd.com/Search?keyword=%E6%89%8B%E6%9C%BA&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&cid2=653&cid3=655&page='+str(2*n-1)
head = {'authority': 'search.jd.com',
'method': 'GET',
'path': '/s_new.php?keyword=%E6%89%8B%E6%9C%BA&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&wq=%E6%89%8B%E6%9C%BA&cid2=653&cid3=655&page=4&s=84&scrolling=y&log_id=1529828108.22071&tpl=3_M&show_items=7651927,7367120,7056868,7419252,6001239,5934182,4554969,3893501,7421462,6577495,26480543553,7345757,4483120,6176077,6932795,7336429,5963066,5283387,25722468892,7425622,4768461',
'scheme': 'https',
'referer': 'https://search.jd.com/Search?keyword=%E6%89%8B%E6%9C%BA&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&wq=%E6%89%8B%E6%9C%BA&cid2=653&cid3=655&page=3&s=58&click=0',
'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36',
'x-requested-with': 'XMLHttpRequest',
'Cookie':'qrsc=3; pinId=RAGa4xMoVrs; xtest=1210.cf6b6759; ipLocation=%u5E7F%u4E1C; _jrda=5; TrackID=1aUdbc9HHS2MdEzabuYEyED1iDJaLWwBAfGBfyIHJZCLWKfWaB_KHKIMX9Vj9_2wUakxuSLAO9AFtB2U0SsAD-mXIh5rIfuDiSHSNhZcsJvg; shshshfpa=17943c91-d534-104f-a035-6e1719740bb6-1525571955; shshshfpb=2f200f7c5265e4af999b95b20d90e6618559f7251020a80ea1aee61500; cn=0; 3AB9D23F7A4B3C9B=QFOFIDQSIC7TZDQ7U4RPNYNFQN7S26SFCQQGTC3YU5UZQJZUBNPEXMX7O3R7SIRBTTJ72AXC4S3IJ46ESBLTNHD37U; ipLoc-djd=19-1607-3638-3638.608841570; __jdu=930036140; user-key=31a7628c-a9b2-44b0-8147-f10a9e597d6f; areaId=19; __jdv=122270672|direct|-|none|-|1529893590075; PCSYCityID=25; mt_xid=V2_52007VwsQU1xaVVoaSClUA2YLEAdbWk5YSk9MQAA0BBZOVQ0ADwNLGlUAZwQXVQpaAlkvShhcDHsCFU5eXENaGkIZWg5nAyJQbVhiWR9BGlUNZwoWYl1dVF0%3D; __jdc=122270672; shshshfp=72ec41b59960ea9a26956307465948f6; rkv=V0700; __jda=122270672.930036140.-.1529979524.1529984840.85; __jdb=122270672.1.930036140|85.1529984840; shshshsID=f797fbad20f4e576e9c30d1c381ecbb1_1_1529984840145'
}
r = requests.get(url, headers=head)
#指定編碼方式,不然會出現亂碼
r.encoding='utf-8'
html1 = etree.HTML(r.text)
#定位到每一個商品標籤li
datas=html1.xpath('//li[contains(@class,"gl-item")]')
#將抓取的結果儲存到本地CSV檔案中
with open('JD_Phone.csv','a',newline='',encoding='utf-8')as f:
write=csv.writer(f)
for data in datas:
p_price = data.xpath('div/div[@class="p-price"]/strong/i/text()')
p_comment = data.xpath('div/div[5]/strong/a/text()')
p_name = data.xpath('div/div[@class="p-name p-name-type-2"]/a/em')
#這個if判斷用來處理那些價格可以動態切換的商品,比如上文提到的小米MIX2,他們的價格位置在屬性中放了一個最低價
if len(p_price) == 0:
p_price = data.xpath('div/div[@class="p-price"]/strong/@data-price')
#xpath('string(.)')用來解析混夾在幾個標籤中的文字
write.writerow([p_name[0].xpath('string(.)'),p_price[0],p_comment[0]])
f.close()
#定義函式抓取每頁後30條商品資訊
def crow_last(n):
#獲取當前的Unix時間戳,並且保留小數點後5位
a=time.time()
b='%.5f'%a
url='https://search.jd.com/s_new.php?keyword=%E6%89%8B%E6%9C%BA&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&wq=%E6%89%8B%E6%9C%BA&cid2=653&cid3=655&page='+str(2*n)+'&s='+str(48*n-20)+'&scrolling=y&log_id='+str(b)
head={'authority': 'search.jd.com',
'method': 'GET',
'path': '/s_new.php?keyword=%E6%89%8B%E6%9C%BA&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&wq=%E6%89%8B%E6%9C%BA',
'scheme':'https',
'referer': 'https://search.jd.com/Search?keyword=%E6%89%8B%E6%9C%BA&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&wq=%E6%89%8B%E6%9C%BA&cid2=653&cid3=655&page=3&s=58&click=0',
'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36',
'x-requested-with': 'XMLHttpRequest',
'Cookie':'qrsc=3; pinId=RAGa4xMoVrs; xtest=1210.cf6b6759; ipLocation=%u5E7F%u4E1C; _jrda=5; TrackID=1aUdbc9HHS2MdEzabuYEyED1iDJaLWwBAfGBfyIHJZCLWKfWaB_KHKIMX9Vj9_2wUakxuSLAO9AFtB2U0SsAD-mXIh5rIfuDiSHSNhZcsJvg; shshshfpa=17943c91-d534-104f-a035-6e1719740bb6-1525571955; shshshfpb=2f200f7c5265e4af999b95b20d90e6618559f7251020a80ea1aee61500; cn=0; 3AB9D23F7A4B3C9B=QFOFIDQSIC7TZDQ7U4RPNYNFQN7S26SFCQQGTC3YU5UZQJZUBNPEXMX7O3R7SIRBTTJ72AXC4S3IJ46ESBLTNHD37U; ipLoc-djd=19-1607-3638-3638.608841570; __jdu=930036140; user-key=31a7628c-a9b2-44b0-8147-f10a9e597d6f; areaId=19; __jdv=122270672|direct|-|none|-|1529893590075; PCSYCityID=25; mt_xid=V2_52007VwsQU1xaVVoaSClUA2YLEAdbWk5YSk9MQAA0BBZOVQ0ADwNLGlUAZwQXVQpaAlkvShhcDHsCFU5eXENaGkIZWg5nAyJQbVhiWR9BGlUNZwoWYl1dVF0%3D; __jdc=122270672; shshshfp=72ec41b59960ea9a26956307465948f6; rkv=V0700; __jda=122270672.930036140.-.1529979524.1529984840.85; __jdb=122270672.1.930036140|85.1529984840; shshshsID=f797fbad20f4e576e9c30d1c381ecbb1_1_1529984840145'
}
r = requests.get(url, headers=head)
r.encoding = 'utf-8'
html1 = etree.HTML(r.text)
datas = html1.xpath('//li[contains(@class,"gl-item")]')
with open('JD_Phone.csv','a',newline='',encoding='utf-8')as f:
write=csv.writer(f)
for data in datas:
p_price = data.xpath('div/div[@class="p-price"]/strong/i/text()')
p_comment = data.xpath('div/div[5]/strong/a/text()')
p_name = data.xpath('div/div[@class="p-name p-name-type-2"]/a/em')
if len(p_price) == 0:
p_price = data.xpath('div/div[@class="p-price"]/strong/@data-price')
write.writerow([p_name[0].xpath('string(.)'),p_price[0],p_comment[0]])
f.close()
if __name__=='__main__':
for i in range(1,101):
#下面的print函式主要是為了方便檢視當前抓到第幾頁了
print('***************************************************')
try:
print(' First_Page: ' + str(i))
crow_first(i)
print(' Finish')
except Exception as e:
print(e)
print('------------------')
try:
print(' Last_Page: ' + str(i))
crow_last(i)
print(' Finish')
except Exception as e:
print(e)
三、執行結果
執行結果如下,一共6000條資訊。根據價格排列後發現有些重複的資訊,不清楚是同一商品不同店家,還是抓重了。
水平有限,如有錯誤望多指教。
---全部文章: 京東爬蟲 、鏈家爬蟲、美團爬蟲、微信公眾號爬蟲、字型反爬、Django筆記、阿里雲部署、vi\vim入門、 Git基本操作 ----
更多案例持續更新,歡迎關注個人公眾號! 第一時間獲得推送
相關文章
- Python爬蟲爬取淘寶,京東商品資訊Python爬蟲
- 京東商品圖片 自動下載 抓取 c# 爬蟲C#爬蟲
- Python爬蟲抓取股票資訊Python爬蟲
- Java爬蟲系列二:使用HttpClient抓取頁面HTMLJava爬蟲HTTPclientHTML
- 電商API介面:京東按關鍵字搜尋商品 批次抓取 資料爬蟲API爬蟲
- Javascript抓取京東、淘寶商品資料JavaScript
- 如何利用BeautifulSoup選擇器抓取京東網商品資訊
- python 爬蟲實戰專案--爬取京東商品資訊(價格、優惠、排名、好評率等)Python爬蟲
- 用java爬取京東商品頁注意點Java
- 如何用python爬蟲分析動態網頁的商品資訊?Python爬蟲網頁
- Python爬蟲,抓取淘寶商品評論內容!Python爬蟲
- python爬蟲抓取哈爾濱天氣資訊(靜態爬蟲)Python爬蟲
- 爬蟲抓取網頁資料原理爬蟲網頁
- 【京東】商品list列表採集+類目下的商品列表資料採集
- Python爬蟲實戰:爬取淘寶的商品資訊Python爬蟲
- 編寫web2.0爬蟲——頁面抓取部分Web爬蟲
- 爬蟲例項-淘寶頁面商品資訊獲取爬蟲
- Python爬蟲抓取知乎所有使用者資訊Python爬蟲
- 爬蟲app資訊抓取之apk反編譯抓取爬蟲APPAPK編譯
- Python爬蟲之Js逆向案例-拼多多商品詳情資料&商品列表資料&商品優惠券資料Python爬蟲JS
- 淘寶拼多多京東上貨必備API 商品詳情頁資料抓取 APP商品詳情原資料APIAPP
- Python爬蟲工具列表Python爬蟲
- Python大神利用正規表示式教你搞定京東商品資訊Python
- 如何使用代理IP進行資料抓取,PHP爬蟲抓取亞馬遜商品資料PHP爬蟲亞馬遜
- 爬蟲利器Pyppeteer的介紹和使用 爬取京東商城書籍資訊爬蟲
- 京東商品詳情介面,京東商品優惠券介面,京東商品分析資料介面,京東API介面封裝程式碼API封裝
- 爬蟲抓取網頁的詳細流程爬蟲網頁
- python爬京東(帶GUI)PythonGUI
- python爬蟲--招聘資訊Python爬蟲
- Python實現拼多多商品資訊抓取方法Python
- 用Python爬蟲抓取代理IPPython爬蟲
- 如何用Python爬資料?(一)網頁抓取Python網頁
- 如何讓Python爬蟲一天抓取100萬張網頁Python爬蟲網頁
- Python爬蟲教程-18-頁面解析和資料提取Python爬蟲
- 爬蟲原理與資料抓取爬蟲
- Python網路爬蟲抓取動態網頁並將資料存入資料庫MYSQLPython爬蟲網頁資料庫MySql
- Python爬蟲實戰之(四)| 模擬登入京東商城Python爬蟲
- Python爬蟲新手教程:手機APP資料抓取 pyspiderPython爬蟲APPIDE