眾所周知,動態網站通常使用例如ajax等異步加載技術來加載網頁,相比於靜態網頁,動態網頁通常包含多個請求,且數據往往並不存在於網頁源碼中,我們便需要通過抓包來尋找數據所在的請求並分析,編寫響應的爬蟲代碼。動態網站的爬取包含下以下三個步驟:抓包,分析參數,提取數據。(以下使用爬取b站評論來作為講解案例)
一、抓包
抓包有很多方式,比較常見的有用例如fiddle這種抓包軟件以及瀏覽器自帶的開發者調試工具(即f12),這里只介紹chrome的f12。
f12里有許多的菜單,這里我們只需要用到network,下面是我們會經常用到的功能





二、分析參數
異步數據包不像網頁一樣有着獨一無二的uri,作為傳遞數據的api,網站通常只會使用一個api來傳遞一類的數據,並通過包內的參數來通知服務器后台應該傳回什么數據,而我們需要分析的參數便是這些影響后台的關鍵數據。
點開我們已經定位到的包,選中header,可以看到有幾個下拉欄
其中有三個欄目是我們需要關注的:
1.Respuest Headers
請求頭,在我們爬靜態網站的時候也同樣會用到的一組參數,例如user-agent,referer等字段,有些網站會在請求頭內傳遞一些數據來通知后台,主要還是為了反爬,除了user-agent和referer之外其他的字段很少用到,具體情況具體分析,爬的時候注意即可。
2.Form data
請求體,只存在於POST請求,也同樣是一組需要分析的參數,因為我們很少會爬到POST請求的api,所以不展開說。
3.Query String Parameters
這是最重要的一組參數,存在於url當中,url鏈接問號后面的那一串字符串就是用來傳這組參數的,不過在f12中我們可以直觀的看到,如下圖
接下來我們需要開始分析這些參數,找出哪些是有用的,哪些是不需要傳的,哪些又是沒用但是需要傳的。這里沒有一個很萬金油的方法,無非就是用刪改參數后訪問並檢查傳過來的數據,或者尋找使用同一api的事件,對比有什么不同,我們可以用python shell或者寫個python腳本用來測試,例如
import requests header = { 'referer': 'https://www.bilibili.com/', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36' } query = { 'callback': 'jQuery172015271738099074472_1610803920156', 'jsonp': 'jsonp', 'pn': 1, 'type': 1, 'oid': 412935552, 'sort': 2, '_': 1610804916511 } url = 'https://api.bilibili.com/x/v2/reply?callback={}&jsonp={}&pn={}&type={}&oid={}&sort={}&_={}' print(requests.get(url.format(query['callback'],query['jsonp'],query['pn'],query['type'],query['oid'],query['sort'],query['_']),headers=header).text)
測試完后我們可知參數callback、jsonp、_是不需要的,type是需要但無意義的,pn表示頁數,sort表示排序方式(即熱度排序和最新排序),oid指定唯一一個視頻(但不是av號),因此我們便可以通過循環pn來把所有的評論都給爬到。
三、提取數據
api大部分采用json數據格式傳輸數據,當然也有直接將參數加到網頁url里傳回html的情況(用bs解析即可),解析json我們需要用到json庫,這里不再詳細講關於json的知識(需要的話去百度查
如圖所示,我們要找的路徑即為root -> data -> replies。每一條評論的內容、作者、時間等都在這里
四、總結
關於動態網站的爬取主要還是在於對異步加載這類前端技術的認識程度,以及對於web開發的理解,雖然作為爬蟲工具人,但前后端的技術學習那是一個沒落下,甚至於某些網站用js來反爬,難度又能上一級。不過對於數據挖掘來說這種基本的爬蟲技術已經夠用,網路上90%的數據爬取都是沒問題的。