1.首先打开B站的首页,热门视频
2.按住F12打开浏览器的开发者模式,点击网络,旁边左上角有搜索框,刷新页面,搜索某一个热门视频的id,找到数据包
3.例如热门第一个视频,“爱意”
在标头能看到请求url,这也是要爬取的目标url
4.复制url地址,浏览器中打开,发现是json数据
5.其中的元素一一对应热门视频的信息
'视频标题':title,
'视频类型':tname,
'播放量':view,
'弹幕量':danmaku,
'评论数量':reply,
'收藏数量':favorite,
'投币数量':coin,
'分享数量':share,
'点赞量':like
6.这里主要爬取这部分信息。当继续往下翻页时候,刷新出新的数据,找到对应的url
查看两个url所变化的值
由此可见变化的值为 pn,w_rid,wts
pn:变化规律,每次翻页加1
wts:时间戳, 可用内置模块time.time()获取当前时间戳 (自己生成)
7.这里主要解决w_rid参数的变化。
8.在浏览器中打开开发者模式,控制台中搜索w_rid参数
9.点击找到对应的网页源代码部分,设置断点,再次往下刷新页面查看使w_rid数据变化的程序部分 。(若出现多个数据包中包含w_rid参数,分别打上断点即可,往下浏览使得页面刷新,自动暂停的地方即参数变化所在部分)
10.可看出w_rid的生成规律 w_rid: L(m + u),这里L是一个标准的MD5算法
查看代码可知,m = f.join("&");
再查看 f的值,如下
0: "pn=6"
1: "ps=20"
2: "web_location=333.934"
3: "wts=1709810979"
再次往下浏览刷新页面,再次断点时候,查看f的值,变化的值为"pn = 7",以及时间轴wts的变化
由此可知,变化的值为 每次翻页时候加1的pn;以及随时间变化的时间轴wts。
11.查看m中的数据,pn=6&ps=20&web_location=333.934&wts=1709810979"
由页面源码可知,m=f.join("&")意思即将f中的值用 & 号来链接
多次刷新发现u为固定值,且u = "ea1db124af3c7062474693fa704f4ff8"
之后编辑代码生成m的值,这里先使得pn=1,生成w_rid代码如下所示
wts = int(time.time())
f = [
'pn=1',
'ps=20',
'web_location=333.934',
f'wts={wts}',
]
m = '&'.join(f)
u = "ea1db124af3c7062474693fa704f4ff8"
string = m+u
print(string)
md = hashlib.md5(string.encode()) # 创建md5对象
w_rid = md.hexdigest() # md5加密
print(w_rid)
12.则变化后的请求地址为
url = f"https://api.bilibili.com/x/web-interface/popular?ps=20&pn=1&web_location=333.934&w_rid={w_rid}&wts={wts}"
13.完整代码,这里先爬取十页的数据。
import requests
import time
import hashlib
import csv
f = open('分页爬取热门视频信息.csv',mode='a',encoding='utf_8_sig',newline='')
csv_write = csv.DictWriter(f, fieldnames=[
'视频标题',
'视频类型',
'播放量',
'弹幕量',
'评论数量',
'收藏数量',
'投币数量',
'分享数量',
'点赞量',
])
csv_write.writeheader()
#处理变化参数
for i in range(1,11): #爬取十页的数据
wts = int(time.time())
f = [
f'pn={i}',
'ps=20',
'web_location=333.934',
f'wts={wts}',
]
m = '&'.join(f)
u = "ea1db124af3c7062474693fa704f4ff8"
string = m+u
md = hashlib.md5(string.encode()) # 创建md5对象
w_rid = md.hexdigest() # md5加密
url = f"https://api.bilibili.com/x/web-interface/popular?ps=20&pn={i}&web_location=333.934&w_rid={w_rid}&wts={wts}"
print(f'正在爬取第{i}页信息,对应请求地址为{url}')
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0',
'Cookie': #放入自己浏览器中cookie
}
response = requests.get(url=url, headers=headers)
json_data = response.json()
for index in json_data['data']['list']:
title = index['title'] # 视频标题
tname = index['tname'] # 视频类型
view = index['stat']['view'] # 播放量
danmaku = index['stat']['danmaku'] # 弹幕量
reply = index['stat']['reply'] # 评论数量
favorite = index['stat']['favorite'] # 收藏数量
coin = index['stat']['coin'] # 投币数量
share = index['stat']['share'] # 分享数量
like = index['stat']['like'] # 点赞量
dit = {
'视频标题': title,
'视频类型': tname,
'播放量': view,
'弹幕量': danmaku,
'评论数量': reply,
'收藏数量': favorite,
'投币数量': coin,
'分享数量': share,
'点赞量': like
}
csv_write.writerow(dit)
14.查看爬取的结果
15.分页爬取目标完成,之后进行数据分析以及可视化。