1. 程式人生 > >Python爬蟲實例:爬取B站《工作細胞》短評——異步加載信息的爬取

Python爬蟲實例:爬取B站《工作細胞》短評——異步加載信息的爬取

localtime pre global web for short sco 網頁解析 save

《工作細胞》最近比較火,bilibili 上目前的短評已經有17000多條。

先看分析下頁面

技術分享圖片

右邊 li 標簽中的就是短評信息,一共20條。一般我們加載大量數據的時候,都會做分頁,但是這個頁面沒有,只有一個滾動條。

隨著滾動條往下拉,信息自動加載了,如下圖,變40條了。由此可見,短評是通過異步加載的。

技術分享圖片

我們不可能一次性將滾動條拉到最下面,然後來一次性獲取全部的數據。既然知道是通過異步來加載的數據,那麽我們可以想辦法直接去獲取這些異步的數據。

打開 Network 查看分析 http 請求,可以點擊 XHR 過濾掉 img、css、js 等信息。這時我們發現了一些 fetch。fetch 我對它的了解就是一個比 ajax 更高級更好用的 API,當然這肯定是不準確的,但並並不影響我們的爬蟲。

技術分享圖片

我們可以看到,其中返回的就是我們需要的內容,json 格式,一共20條,total 屬性就是總的數目。分析一下 url 地址:https://bangumi.bilibili.com/review/web_api/short/list?media_id=102392&folded=0&page_size=20&sort=0&cursor=76729594906127

media_id 想必就是《工作細胞》的 id 了;

folded 不知道是啥,可以不管;

page_size 是每頁的條數;

sort 排序,看名字就知道,找到排序的選項,試了下,果然是的,默認0,最新1;

技術分享圖片

cursor,字面意思的光標,猜測應該是指示本次獲取開始的位置的,展開獲取到的 json,發現其中包含有 cursor 屬性,對比以後可以發現,url中的值跟上一次返回結果中的最後一條中的 cursor 的值是一致的。

好了,至此,頁面已經分析清楚了,爬取的方式也明顯了,根本不用管網頁,直接根據 fetch 的地址獲取 json 數據就可以了,連網頁解析都省了,超級的方便。

下面的完整的代碼:(如果 fake_useragent 報錯,就手動寫個 User-Agent 吧,那個庫極度的不穩定)

import csv
import os
import time
import requests
from fake_useragent import UserAgent

curcount = 0


def main():
    url = https://bangumi.bilibili.com/review/web_api/short/list?media_id=102392&folded=0&page_size=20&sort=0
crawling(url) def crawling(url): print(f正在爬取:{url}) global curcount headers = {"User-Agent": UserAgent(verify_ssl=False).random} json_content = requests.get(url, headers).json() total = json_content[result][total] infolist = [] for item in json_content[result][list]: info = { author: item[author][uname], content: item[content], ctime: time.strftime(%Y-%m-%d %H:%M:%S, time.localtime(item[ctime])), likes: item[likes], disliked: item[disliked], score: item[user_rating][score] } infolist.append(info) savefile(infolist) curcount += len(infolist) print(f當前進度{curcount}/{total}) if curcount >= total: print(爬取完畢。) return nexturl = fhttps://bangumi.bilibili.com/review/web_api/short/list? fmedia_id=102392&folded=0&page_size=20&sort=0&cursor={json_content["result"]["list"][-1]["cursor"]} time.sleep(1) crawling(nexturl) def savefile(infos): with open(WorkingCell.csv, a, encoding=utf-8) as sw: fieldnames = [author, content, ctime, likes, disliked, score] writer = csv.DictWriter(sw, fieldnames=fieldnames) writer.writerows(infos) if __name__ == __main__: if os.path.exists(WorkingCell.csv): os.remove(WorkingCell.csv) main()

Python爬蟲實例:爬取B站《工作細胞》短評——異步加載信息的爬取