請注意,爬蟲的使用應遵守網站的爬蟲政策和法律法規,不要對網站造成不必要的負擔或違反服務條款。
透過瀏覽器審查元素檢視網路日誌,發現每次獲取動態資訊的請求地址都相同,首次載入時offset為空:
https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space?host_mid=25470223&offset=
隨著網頁的不斷下拉,offset引數無規律變換,第二次及以後的offset就在上一次次請求返回的json裡的"offset"中,將"offset"的值帶入下一次請求的引數中即可迴圈爬取。動態下拉到頭時,json中"has_more"會由true變為false,可以以此判斷是否結尾。此時的程式碼如下:
def fetch_data(offset):
# 請求的URL
url = "https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space"
# 請求引數
params = {
"offset": offset,
"host_mid": 25470223
}
# 傳送請求
response = requests.get(url, params=params, headers=headers)
# 解析JSON資料
data = response.json()
print(data) # 自行處理json物件
# 檢查是否還有更多資料
if data['data']['has_more']:
# 如果有更多資料,使用新的offset發起新的請求
fetch_data(data['data']['offset'])
# 從offset為空開始
fetch_data("")
直接爬取時,無法直接獲取到資料,經網上查詢為鑑權錯誤
{"code":-352,"message":"-352","ttl":1}
這時需要新增請求頭及必要的cookie,新增後可以正常爬取,"response.text"即為響應json字串,可自行儲存後單獨處理。並新增延時引數防止以後都逛不了B站:
import json
import time
import requests
# 新增請求頭
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'Accept-Language': 'zh-CN,zh;q=0.9',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36',
'Cookie':'buvid3=...; b_nut=...; _uuid=...; buvid4=...;' # up主動態頁審查元素自行獲取,必傳
}
def fetch_data(offset):
# 每次請求時延時0.1秒
time.sleep(0.1)
# 請求的URL
url = "https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space"
# 請求引數
params = {
"offset": offset,
"host_mid": 25470223 # up主id,up主動態頁審查元素自行獲取
}
# 傳送請求
response = requests.get(url, params=params, headers=headers)
# 解析JSON資料
data = response.json()
print(data) # 自行處理json物件
# 檢查是否還有更多資料
if data['data']['has_more']:
# 如果有更多資料,使用新的offset發起新的請求
fetch_data(data['data']['offset'])
# 從offset為空開始
fetch_data("")