如何在Python中正确解析Facebook导出的UTF-8字节转义JSON?
修复Facebook导出JSON的编码错误
我之前处理过好几次Facebook数据导出的这个编码坑,简直是反直觉的错误——明明应该直接转义Unicode码点,结果Facebook先把字符转成UTF-8字节,再把每个字节单独当成Unicode码点做了\u转义,导致用Python的json库解析后出现乱码(比如á变成á)。下面给你两种实用的解决方法:
方法一:解析后递归修复乱码字符串
这个方法最简单直接,利用Latin-1编码的单字节映射特性来还原:
Latin-1(ISO-8859-1)的编码规则是:每个Unicode码点U+0000到U+00FF对应一个字节0x00到0xFF。所以解析出来的乱码字符(比如Ã对应U+00C3,¡对应U+00A1),用Latin-1编码就能还原成原始的UTF-8字节,再解码成UTF-8就得到正确字符了。
代码示例
import json def fix_encoding(obj): """递归遍历JSON结构,修复所有乱码字符串""" if isinstance(obj, str): # 核心步骤:Latin-1编码回字节 → UTF-8解码为正确字符 return obj.encode('latin-1').decode('utf-8') elif isinstance(obj, list): return [fix_encoding(item) for item in obj] elif isinstance(obj, dict): return {key: fix_encoding(value) for key, value in obj.items()} else: # 非字符串类型(数字、布尔值等)直接返回 return obj # 读取并解析原始JSON with open('facebook_export.json', 'r', encoding='utf-8') as f: raw_data = json.load(f) # 修复编码问题 fixed_data = fix_encoding(raw_data) # 验证结果:比如打印某个包含特殊字符的字段 print(fixed_data['some_field_with_accents'])
注意事项
如果你的JSON里同时存在正确的Unicode转义(比如\u00e1),这个方法会导致正确的字符解码失败(因为á的Latin-1编码是0xE1,而0xE1不是有效的UTF-8单字节)。这种情况下建议用下面的方法。
方法二:预处理原始JSON文本,修复转义序列
这个方法直接在解析前修改原始文本,只针对Facebook错误生成的\u00XX转义序列(对应UTF-8字节)进行修复,不会影响正常的Unicode转义。
代码示例
import json import re # 以二进制模式读取原始文件,避免编码干扰 with open('facebook_export.json', 'rb') as f: raw_bytes = f.read() # 先把字节转成Latin-1文本,保证每个字节对应一个字符 raw_text = raw_bytes.decode('latin-1') # 匹配所有Facebook错误生成的`\u00XX`转义(XX是UTF-8字节的十六进制) pattern = re.compile(r'\\u00([0-9a-fA-F]{2})') def replace_escape(match): # 提取十六进制字节值,转成对应的字符 byte_hex = match.group(1) return bytes.fromhex(byte_hex).decode('latin-1') # 替换所有错误转义 processed_text = pattern.sub(replace_escape, raw_text) # 解析修复后的文本 fixed_data = json.loads(processed_text)
原理说明
Facebook把á(U+00E1)转成了UTF-8字节0xC3和0xA1,然后分别转义成\u00c3和\u00a1。我们通过正则找到所有\u00XX格式的转义,把它们还原成对应的字节,再转成字符,这样原始的UTF-8字节序列就被恢复了,解析后自然得到正确的Unicode字符。
内容的提问来源于stack exchange,提问作者user6247
相关产品推荐
相关产品推荐

