文章目录
本篇博文记录一下爬取小破站弹幕的主要思路以及完整代码
一.前言
审核求过
小破站在2023年将弹幕接口的返回值从.xml改成了.so文件
比如下面这个地址:
返回值示例:
很明显部分数据是被加密了。
二.配置Protobuf 环境&生成编译文件
1.配置Protobuf 环境
通过搜索知道了,这种格式叫做**Protobuf **,这个格式为二进制编码传输
Protobuf(Protocol Buffers)是一种轻量级的数据序列化协议,由Google开发。它可以用于结构化数据的序列化和反序列化,常用于网络通信、数据存储和配置文件等场景。
Protobuf使用简洁的语法定义数据结构,然后通过编译器生成相应的代码,用于在不同的编程语言中进行数据的序列化和反序列化操作。相比于其他序列化协议,Protobuf具有更高的性能和更小的数据体积。
使用Protobuf,你可以定义消息的字段类型、字段名称和字段顺序等信息,然后通过编译器生成的代码来进行数据的读写操作。Protobuf支持多种编程语言,包括C++、Java、Python等,因此可以在不同的平台和语言之间进行数据的传输和交换。
总的来说,Protobuf协议是一种高效、灵活和可扩展的数据序列化协议,适用于各种场景下的数据交换和存储需求。
简单来说就是一种比XML还轻量的数据。
需要解密这种格式数据需要我们下载Protobuf 的编译器(我的电脑是windows64位的,直接下载win64位即可)
https://github.com/protocolbuffers/protobuf/releases/tag/v3.17.3
下载完成后,解压出来
其中bin目录为可执行程序存放目录,我们把它加到环境变量里来:
win10的操作步骤是:
右击“此电脑”-高级系统设置-环境变量-双击path-新建-输入值-确定
在cmd中输入protoc来验证我们的配置是否成功,如果你的控制台输出结果和我的一样,那么恭喜你,环境配置成功
2.生成编译文件
首先要去下载dm.proto
然后在控制台中输入
protoc --python_out=. dm.proto
就会在同目录下生成一个dm_pb2.py的文件
这个文件很关键。
三.解析弹幕
将上一步编译出来的dm_pb2.py文件放在脚本的同一级,这里演示解析本地.so文件
撰写代码
import dm_pb2
from google.protobuf import text_format
my_seg = dm_pb2.DmSegMobileReply()withopen('./seg.so','rb')as f:
DATA = f.read()
my_seg.ParseFromString(DATA)
parse_data = text_format.MessageToString(my_seg.elems[0], as_utf8=True)print(parse_data)
输出结果
四.自动解析弹幕
这里本人贡献出一种自动解析弹幕,输入视频的BVID即可
import json
import requests
import google.protobuf.text_format as text_format
import dm_pb2 as Danmaku
import re
classBEngine():"""
bilibili引擎
"""def__init__(self):
self.headers ={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36"}defdo_request(self, url):
headers ={"user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36"}
r = requests.get(url, headers=headers)if r.status_code ==200:
r.encoding ='utf-8'return r.text
else:returnFalsedefget_video_cid(self, bvid):"""
通过bvid获取cid
:param bvid:
:return:
"""
api_url = f'https://api.bilibili.com/x/web-interface/view?bvid={bvid}'try:
html = self.do_request(api_url)if html:
_json = json.loads(html)
cid = _json['data'].get('cid')return cid
else:returnFalseexcept:returnFalsedefbvid_to_avid(self, bvid):"""
通过bvid获取avid
:param bvid:
:return:
"""
table ='fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF'
tr ={}for i inrange(58):
tr[table[i]]= i
s =[11,10,3,8,4,6]
xor =177451812
add =8728348608defdec(x):
r =0for i inrange(6):
r += tr[x[s[i]]]*58** i
return(r - add)^ xor
return dec(bvid)defget_danmu(self, avid, cid):"""
通过so文件获取解密后的弹幕列表
:return:
"""
result =[]
url ='http://api.bilibili.com/x/v2/dm/web/seg.so'
params ={'type':1,# 弹幕类型'oid': cid,# cid'pid': avid,# avid'segment_index':1# 弹幕分段}
resp = requests.get(url, params, headers=self.headers)
data = resp.content
danmaku_seg = Danmaku.DmSegMobileReply()
danmaku_seg.ParseFromString(data)for j in danmaku_seg.elems:
parse_data = text_format.MessageToString(j, as_utf8=True)
result.append(parse_data.replace("\n",",").rstrip(","))print(result)return result
defparse_danmu(self, danmu_list):"""
解析出每个弹幕列表内容
:param danmu_list:
:return:
"""
result =[]for each_dm in danmu_list:
res = re.findall('''id: \d+,progress: (\d+),mode: (\d+),fontsize: (\d+),color: (\d+),midHash: "(.*?)",content: "(.*?)",ctime: (\d+),weight: (\d+),idStr: "(\d+)"''',
each_dm)if res andlen(res[0])==9:
item ={"progress": res[0][0],"mode": res[0][1],"fontsize": res[0][2],"color": res[0][3],"midHash": res[0][4],"content": res[0][5],"ctime": res[0][6],"weight": res[0][7],"idStr": res[0][8],}
result.append(item)else:continuereturn result
defgetdanmu_format(self, bvid):"""
弹幕直接格式化
:param bvid:
:return:
"""
avid = e.bvid_to_avid(bvid)
cid = e.get_video_cid(bvid)
danmu_raw = self.get_danmu(avid, cid)return self.parse_danmu(danmu_raw)if __name__ =='__main__':
e = BEngine()
bvid ="BV1Dz4y1L7hj"print(e.getdanmu_format(bvid))
输出结果示例
五.总结
本次通过调研protobuf协议通过搭建环境,使用Python撰写代码实现了对B战弹幕的解析,对于大多数人而言,可能搭建本地环境那里有些难,在此奉上封装好的dm_pb2.py文件点击下载,大家放在自己的脚本同级目录下即可。最后祝大家玩得开心能给点个赞么?
六.参考
小破站弹幕 Protobuf 格式解析
Python实现对Bilibili视频点赞等信息的爬取
小破站弹幕 so文件解析/逆序列化
python进行小破站av号和bv号的转换
版权归原作者 懷淰メ 所有, 如有侵权,请联系我们删除。