具体步骤:
1.指定url网址
在这里随便点开B站首页推送的一个视频内容
2.打开开发者工具,点击网络刷新界面,下滑页面数据让数据加载出来,随便选择一条评论复制,粘贴到开发工具中的搜索框中,找到对应的包
这里的url即为保存评论所在的网址。
3.查看预览,能看到评论信息再replies中,这里分别爬取评论内容,点赞数量,IP属地,性别信息。
4.单页爬取代码:
import requests
import csv
f = open('data.csv', mode='w', encoding='utf-8', newline='') #创建文件对象,保存数据
csv_writer = csv.DictWriter(f, fieldnames=[
'昵称',
'性别',
'IP',
'评论',
'点赞',
])
csv_writer.writeheader()
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',
'Referer':'https://www.bilibili.com/'
}
url = 'https://api.bilibili.com/x/v2/reply/wbi/main?oid=1100057498&type=1&mode=3&pagination_str=%7B%22offset%22:%22%22%7D&plat=1&seek_rpid=&web_location=1315875&w_rid=fe513cbd5f86cae0292f3f8114b6e276&wts=1706754224'
response = requests.get(url=url, headers=headers)
json_data = response.json()
#解析数据(字典取值)
#提取数据所在的列表
replies = json_data['data']['replies']
for index in replies:
#提取评论内容
message = index['content']['message'].replace('\n', ',') #评论信息(replace替换换行符)
like = index['like'] #点赞数
name = index['member']['uname'] #昵称
sex = index['member']['sex'] #性别
location = index['reply_control']['location'].replace('IP属地:', '')#ip属地
dit = {
'昵称':name,
'性别':sex,
'IP':location,
'评论':message,
'点赞':like,
}
csv_writer.writerow(dit)
print(dit)
5.实现翻页爬取时,找到变化的对应参数
6.变化的参数有三个
pagination_str: 第一个参数能直接在第一页的返回数据包中找到
w_rid: 需要js逆向
wts:时间戳, 可用内置模块time.time()获取当前时间戳 (自己生成)
7.这里处理w_rid参数,在源码页面中搜索,w_rid参数,查看所处位置,进行断点检测
变化的参数为 Jt+wt,这里的wt为固定值。并且采取了md5加密的方式,分析可得Jt的值为en中内容的综合,en内容则为负载中的固定值。
完整代码实现翻页爬取:
#B站评论分页爬取
import requests
import csv
import hashlib
import time
from urllib.parse import quote
import re
#实现翻页爬取
#w_rid: 需要js逆向 md5(jt + wt) Jt = en.join("&") wt="ea1db124af3c7062474693fa704f4ff8"固定值
def hash(data,date):
en=[
"mode=3",
"oid=1100057498",
f"pagination_str={quote(data)}",
"plat=1",
"type=1",
"web_location=1315875",
f"wts=f{date}", #时间戳
]
wt = "ea1db124af3c7062474693fa704f4ff8"
Jt = '&'.join(en)
string = Jt + wt
MD5 = hashlib.md5()
MD5.update(string.encode('utf-8'))
w_rid = MD5.hexdigest()
print(w_rid)
return w_rid
def get_content(data):
date = (time.time() *1000)
pagination_str = '{"offset":"{\\"type\\":1,\\"direction\\":1,\\"data\\":{\\"pn\\":%s}}"}' % data
w_rid = hash(pagination_str, date)
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,
'Referer':'https://www.bilibili.com/'
}
url = 'https://api.bilibili.com/x/v2/reply/wbi/main?'
data = {
'oid': '1100057498',
'type': '1',
'mode': '3',
'pagination_str': '{"offset":"{\\"type\\":1,\\"direction\\":1,\\"data\\":{\\"pn\\":%s}}"}'%data,
'plat':'1',
'web_location': '1315875',
'w_rid': w_rid,
'wts':date,
}
response = requests.get(url=url, params=data, headers=headers)
json_data = response.json()
print(json_data)
#解析数据(字典取值)
#提取数据所在的列表
replies = json_data['data']['replies']
for index in replies:
#提取评论内容
message = index['content']['message'].replace('\n', ',') #评论信息(replace替换换行符)
like = index['like'] #点赞数
name = index['member']['uname'] #昵称
sex = index['member']['sex'] #性别
location = index['reply_control']['location'].replace('IP属地:', '')#ip属地
dit = {
'昵称':name,
'性别':sex,
'IP':location,
'评论':message,
'点赞':like,
}
csv_writer.writerow(dit)
print(dit)
#提取下一页的参数
next_offset = json_data['data']['cursor']['pagination_reply']['next_offset'] #第一个参数的获取
next_page = re.findall('cursor\":(\d+)', next_offser)[0]
return next_page
if __name__ == '__main__':
f = open('data.csv', mode='w', encoding='utf-8', newline='') # 创建文件对象,保存数据
csv_writer = csv.DictWriter(f, fieldnames=[
'昵称',
'性别',
'IP',
'评论',
'点赞',
])
csv_writer.writeheader()
for page in range(1,11):
next_page = get_content(next_page)
部分爬取结果