Smile_to_destiny 2025-03-30 02:12 采纳率: 50%
浏览 31
已结题

protobuf进行反序列化时持续报错

求解答!

使用protobuf进行反序列化时持续报错,但运行的是给出示例代码啊!

GitHub项目为bilibili-API-collect

项目地址为:https://github.com/SocialSisterYi/bilibili-API-collect

使用的protobuf文件是项目仓库中的grpc_api/bilibili/community/service/dm/v1/dm.proto

项目readme中protobuf弹幕部分的示例代码为:

import requests
import google.protobuf.text_format as text_format
import bilibili.community.service.dm.v1.dm_pb2 as Danmaku

url = 'https://api.bilibili.com/x/v2/dm/web/seg.so'
params = {
    'type': 1,         # 弹幕类型
    'oid': 1176840,    # cid
    'pid': 810872,     # avid
    'segment_index': 1 # 弹幕分段
}
resp = requests.get(url, params)
data = resp.content

danmaku_seg = Danmaku.DmSegMobileReply()
danmaku_seg.ParseFromString(data)

print(text_format.MessageToString(danmaku_seg.elems[0], as_utf8=True))

本人的操作步骤为:在GitHub中下载最新的protobuf编译器,版本为v.6.30.2(Github项目地址为:https://github.com/protocolbuffers/protobuf)。

利用cmd执行生成python可执行文件后,得到后缀为_pb2.py文件后,放入同级目录中运行示例代码。

结果运行时报错为:

Traceback (most recent call last):
  google.protobuf.message.DecodeError: Error parsing message with type 'dm.DmSegMobileReply'
  • 写回答

6条回答 默认 最新

  • AI仙人掌 iFLYTEKA.I开发者大赛获奖者 2025-03-30 06:34
    关注

    可能原因:

    1. 获取的数据不是有效的 protobuf 格式 - 服务器可能返回了错误数据或非 protobuf 数据
    2. protobuf 定义不匹配 - 使用的 .proto 定义与服务器返回的数据结构不一致
    3. 需要请求头 - B站 API 可能需要特定的请求头
    4. 分段索引超出范围 - 该视频可能没有这么多弹幕分段

    解决方案:

    1. 添加必要的请求头
      B站 API 通常需要添加 User-AgentReferer
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
        'Referer': 'https://www.bilibili.com/'
    }
    resp = requests.get(url, params=params, headers=headers)
    
    1. 检查返回数据
      先查看原始数据是什么:
    print(resp.status_code)
    print(resp.headers)
    print(resp.content[:100])  # 查看前100字节
    
    1. 尝试不同的分段索引
      有些视频弹幕较少,可能只有 segment_index=1 有数据:
    params['segment_index'] = 1  # 尝试改为1
    
    1. 确认 CID 和 AVID
      确保你使用的 oid(cid) 和 pid(avid) 是正确的。

    2. 更新 protobuf 定义
      确保你使用的 dm.proto 是最新版本。

    完整修正代码示例:

    import requests
    import google.protobuf.text_format as text_format
    import bilibili.community.service.dm.v1.dm_pb2 as Danmaku
    
    url = 'https://api.bilibili.com/x/v2/dm/web/seg.so'
    params = {
        'type': 1,         # 弹幕类型
        'oid': 1176840,    # cid
        'pid': 810872,     # avid
        'segment_index': 1 # 弹幕分段
    }
    
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
        'Referer': 'https://www.bilibili.com/'
    }
    
    resp = requests.get(url, params=params, headers=headers)
    print(f"Status code: {resp.status_code}")
    
    # 检查是否是protobuf数据
    if resp.content.startswith(b'\x10'):
        try:
            danmaku_seg = Danmaku.DmSegMobileReply()
            danmaku_seg.ParseFromString(resp.content)
            if danmaku_seg.elems:
                print(text_format.MessageToString(danmaku_seg.elems[0], as_utf8=True))
            else:
                print("No danmaku found in this segment.")
        except Exception as e:
            print(f"Error parsing protobuf: {e}")
            print(f"Raw data start: {resp.content[:100]}")
    else:
        print("Response is not a protobuf message:")
        print(resp.text)  # 可能返回了JSON错误信息
    

    如果问题仍然存在,可能需要:

    1. 检查视频是否仍有弹幕(有些老视频弹幕可能被清空)
    2. 获取最新的 protobuf 定义文件
    3. 尝试使用 B站的其他弹幕API端点
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(5条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 3月30日
  • 已采纳回答 3月30日
  • 修改了问题 3月30日
  • 创建了问题 3月30日