Protobuf响应必须反序列化才能解析,核心前提是拥有对应.proto文件并生成Python类;若无.proto,需通过逆向分析、抓包比对或protoc --decode_raw初步探查字段编号与类型。

Protobuf 响应不能直接用 json.loads 或 response.text 解析,必须先反序列化——核心在于你得有对应的 .proto 文件并生成 Python 类。
拿到 .proto 文件是前提,没有它几乎无法可靠解析
爬虫返回的 Protobuf 是二进制,没有 schema 就像看加密报文。常见情况是:响应头含 Content-Type: application/x-protobuf,但服务端不公开 .proto;此时只能靠逆向(如抓包比对字段变化、搜索开源项目中相似结构)或试错式定义。
- 优先检查网页源码、JS 文件、GitHub 仓库、API 文档附录,常藏在
protos/或schema/目录下 - 若只有二进制响应体,可用
protoc --decode_raw < response.bin看字段编号和基础类型(但无字段名) - 生成 Python 类必须用
protoc --python_out=. your_file.proto,生成的your_file_pb2.py才能导入使用
用生成的 _pb2 类调用 ParseFromString() 反序列化
不是所有类都叫 Response,类名取决于 .proto 中的 message 定义。常见错误是直接传入 response.content 却忘了检查 HTTP 状态码或空响应。
安全 Python 代码沙箱:在隔离的沙箱中执行任意 Python 代码,预装 requests、NumPy、pandas 库。返回 stdout、stderr。
- 确保
response.status_code == 200且response.content非空 - 导入时注意路径:如果
user_pb2.py在当前目录,写import user_pb2;若在子包protos/,需加from protos import user_pb2 - 反序列化示例:
msg = user_pb2.UserList() msg.ParseFromString(response.content)
- 若字段是 repeated(即列表),访问方式为
msg.items(不是msg.items_list)
遇到 DecodeError: Error parsing message 怎么排查
这通常不是代码写错,而是二进制格式与预期 message 不匹配——比如用了 A 的类去解 B 的数据,或服务端启用了压缩(如 gzip)、加密、分帧传输。
立即学习“Python免费学习笔记(深入)”;
- 先打印
len(response.content):若长度异常小(如 0 或 1),可能是重定向或鉴权失败 - 检查响应头:
response.headers.get('Content-Encoding'),若为gzip,需先gzip.decompress(response.content) - 确认 wire type 匹配:例如
int32字段传了负数,而定义是uint32,会直接报错 - 用
protoc --decode_raw对比原始字节,看字段编号是否和.proto中一致
真正麻烦的永远不是语法,而是服务端悄悄改了字段类型、加了嵌套层级、或者把多个 message 拼在一个响应体里——这时候光靠 ParseFromString 不够,得结合 io.BytesIO 手动切片或查 length-delimited 编码规则。

















