必须用 bson.decode() 解析 BSON 字节流,如 decode(b'\x1a\x00\x00\x00\x02name\x00\x06\x00\x00\x00alice\x00\x00') → {'name': 'alice'};json.loads() 会因 BSON 是二进制格式而报错。

不能直接用 json.loads() 解析 MongoDB 的 BSON 字节流,必须用 pymongo 自带的解码器或 bson 模块。
从网络抓包或日志里拿到 BSON raw bytes 怎么转成 Python dict?
比如你用 Wireshark 抓到 MongoDB wire protocol 的 reply payload,或者从日志里 dump 出一段 b'\x1a\x00\x00\x00\x02name\x00\x06\x00\x00\x00alice\x00\x00' 这样的字节串——它不是 JSON,也不是 msgpack,是 BSON 二进制格式。
正确做法是调用 bson.decode()(注意不是 bson.loads(),后者不存在):
from bson import decode
<p>raw_bson = b'\x1a\x00\x00\x00\x02name\x00\x06\x00\x00\x00alice\x00\x00'
doc = decode(raw_bson)</p><h1>→ {'name': 'alice'}-
decode()要求输入是bytes,且必须是完整、合法的 BSON document(开头 4 字节是 length) - 如果字节流来自 mongodump 的
.bson文件,注意它可能包含多个文档拼接,需用bson.decode_all()或手动按 length 切分 - 不支持 streaming 解析;整段字节必须加载进内存才能调用
decode()
为什么 json.loads() 会报错:Expecting value?
因为 BSON 是二进制协议,不是文本。即使你用 raw_bson.decode('utf-8') 强转字符串,也会遇到非法 Unicode 字符(比如 \x00、\x02),导致解码失败或静默截断。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
立即学习“Python免费学习笔记(深入)”;
- 典型错误信息:
JSONDecodeError: Expecting value: line 1 column 1 (char 0)或UnicodeDecodeError: 'utf-8' codec can't decode byte 0x00 - BSON 中的字符串以 \x00 结尾,二进制类型(如
ObjectId)用 \x07 标记,这些在 UTF-8 下无意义 - 别试图用正则或字符串替换“修复”后再喂给
json.loads()——语义已丢失,datetime、ObjectId、Binary全部无法还原
如何把 Python dict 再编码回 BSON 并写入文件?
用 bson.encode(),不是 json.dumps().encode()。否则写出去的不是合法 BSON,mongorestore 会拒绝导入。
from bson import encode
from bson.objectid import ObjectId
<p>doc = {'name': 'bob', '_id': ObjectId('65a1b2c3d4e5f67890abcdef')}
encoded = encode(doc) # → bytes,开头 4 字节是总长度
with open('output.bson', 'wb') as f:
f.write(encoded)-
encode()默认不处理datetime以外的扩展类型;若 dict 含Decimal128、Regex等,需传codec_options - 写多个文档时,不要简单拼接
encode(d1) + encode(d2);.bson文件格式要求每个文档独立编码,mongorestore 能自动识别边界 - 避免用
open(..., 'w').write(str(dict))——那只是字符串表示,完全不是 BSON
真正麻烦的是嵌套的 ObjectId、带时区的 datetime 和自定义 Codec;一旦涉及这些,bson.decode() 返回的对象可能含非 JSON-serializable 类型,后续存 JSON 或打日志前得先做类型清洗。

















