b站 实时弹幕和历史弹幕 Protobuf 格式解析

参考:

b站弹幕传输的格式由原来的 xml 改为了 protobuf,这个格式为二进制编码传输,其传输销量远高于原来的 xml,因此在移动端可以减小网络的压力具有一定的优势。但带来的一个问题就是,这个格式的弹幕解析起来变得十分困难,通常从 api 获得的数据直接看是一通乱码,需要特定的方式才能看到真正的内容,让人比较头疼。

B站没有使用 protobuf 协议前的弹幕接口

1、什么是 Protobuf

Protocol buffers are Google's language-neutral, platform-neutral, extensible mechanism for serializing structured data – think XML, but smaller, faster, and simpler. You define how you want your data to be structured once, then you can use special generated source code to easily write and read your structured data to and from a variety of data streams and using a variety of languages.

上面这段话来自谷歌 Protobuf 官网的介绍,简单来讲就是一种传输的协议,比 xml 更小、更快、更简单,更多信息可以见:https://developers.google.com/protocol-buffers/

2、如何解析 Protobuf 的弹幕

2.1 下载 Protoc 编译器

Protoc 是用于将 .proto 文件编译成各种编程语言(如 Python、Golang 等)的编译器,是进行 Protobuf 解析的必要条件,可在下面的链接中下载:https://github.com/protocolbuffers/protobuf

 下载完成后解压出来是 exe 文件,不需要安装,但是需要手动添加到 Path 中。

 通过在终端中运行如下代码来确定是否安装成功:protoc --version

2.2 下载 Protobuf-Python 以便在 Python 中解析 Protobuf

下载地址:https://github.com/protocolbuffers/protobuf

下载完成后解压,然后进入 python 进入目录,

 执行以下命令行代码:

python setup.py clean
python setup.py build
python setup.py install
python setup.py test

2.3 弹幕的 proto 定义并编译

弹幕格式,protobuf 结构体:

dm.proto

syntax = "proto3";

package dm;

message DmSegMobileReply{
  repeated DanmakuElem elems = 1;
}
message DanmakuElem{
  int64 id = 1;
  int32 progress = 2;
  int32 mode = 3;
  int32 fontsize = 4;
  uint32 color = 5;
  string midHash = 6;
  string content = 7;
  int64 ctime = 8;
  int32 weight = 9;
  string action = 10;
  int32 pool = 11;
  string idStr = 12;
}
名称含义类型备注
id弹幕dmIDint64唯一 可用于操作参数
progress视频内弹幕出现时间int32毫秒
mode弹幕类型int321 2 3:普通弹幕
4:底部弹幕
5:顶部弹幕
6:逆向弹幕
7:高级弹幕
8:代码弹幕
9:BAS弹幕
fontsize弹幕字号int3218:小
25:标准
36:大
color弹幕颜色uint32十进制RGB888值
midHash发送者UID的HASHstring用于屏蔽用户和查看用户发送的所有弹幕 也可反查用户ID
content弹幕内容stringutf-8编码
ctime弹幕发送时间int64时间戳
weight权重int32用于智能屏蔽级别
action动作string未知
pool弹幕池int320:普通池
1:字幕池
2:特殊池(代码/BAS弹幕)
idStr弹幕dmID的字符串类型string唯一 可用于操作参数

2.4 解析 seg.so 格式的弹幕数据

示例视频:https://www.bilibili.com/video/av98919207

解析之前需要先安装 python 的 probuf 包: pip install protobuf

编译 proto 结构文件,

protoc --python_out=. dm.proto

执行完成后会生成 dm_pb2.py,代码中引入这个 python 文件,

 dm_pj.py 代码如下:

注意:

  • 实时弹幕 不需要 cookie,直接请求即可得到 seg.so 
  • 历史弹幕 需要 cookie 才能得到 seg.so 
# -*- coding: utf-8 -*-
# @Author  : 
# @Date    :
# @File    : dm_pj.py
# @description : XXX


import json
import requests
from dm_pb2 import DmSegMobileReply
from google.protobuf.json_format import MessageToJson, Parse


b_web_cookie = 'SESSDATA=fd25e2e6%2C1660373048%2C287c9%2A21;'


def get_date_list():
    url = "https://api.bilibili.com/x/v2/dm/history/index?type=1&oid=168855206&month=2022-02"
    headers = {
        'cookie': b_web_cookie
    }
    response = requests.get(url, headers=headers)
    print(json.dumps(response.json(), ensure_ascii=False, indent=4))


def dm_real_time():
    url_real_time = 'https://api.bilibili.com/x/v2/dm/web/seg.so?type=1&oid=168855206&pid=98919207&segment_index=1'
    resp = requests.get(url_real_time)

    DM = DmSegMobileReply()
    DM.ParseFromString(resp.content)
    data_dict = json.loads(MessageToJson(DM))
    # print(data_dict)
    list(map(lambda x=None: print(x['content']), data_dict.get('elems', [])))


def dm_history():
    url_history = 'https://api.bilibili.com/x/v2/dm/web/history/seg.so?type=1&oid=168855206&date=2022-02-23'
    headers = {
        'cookie': b_web_cookie
    }
    resp = requests.get(url_history, headers=headers)
    DM = DmSegMobileReply()
    DM.ParseFromString(resp.content)
    data_dict = json.loads(MessageToJson(DM))
    # print(data_dict)
    list(map(lambda x=None: print(x['content']), data_dict.get('elems', [])))


if __name__ == '__main__':
    # dm_real_time()
    get_date_list()
    # dm_history()
    pass

 执行结果截图:

弹幕对比:

  • 3
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于处理B站弹幕中的protobuf,可以参考以下步骤: 1. 配置和原理:你可以根据提供的两篇博客,学习如何配置protobuf环境和了解protobuf的基本原理。确保将`protoc.exe`配置到环境变量中。 2. 编译生成Python代码:根据提供的指令`protoc --python_out=./ person.proto`,使用protobuf编译器将`.proto`文件编译成Python代码。编译完成后,会在目录下生成`person_pb2.py`文件。 3. 分析弹幕请求:根据提供的代码`var r = a.protoMessage[t].decode(new Uint8Array(i.data)) , o = a.protoMessage[t].toObject(r)`,可以看到这段代码是对返回的数据进行解码和转换。可以通过在代码中打上断点,跟踪代码的执行过程,查看具体的处理逻辑。 综上所述,处理B站弹幕中的protobuf,需要先配置环境并编译生成Python代码,然后根据具体的代码逻辑进行分析和处理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [B站弹幕文件protobuf协议的逆向和还原](https://blog.csdn.net/qq_40734108/article/details/127455489)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [JS逆向加密——B 站弹幕 protobuf 分析](https://blog.csdn.net/qq_39551311/article/details/125933062)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值