如何使用Python读取含UTF-8转义字符的大型JSON文件并转为可读格式
双重编码JSON转义的还原方法
你碰到的不是普通的\uXXXX转义未正常解析的问题,是典型的字符双重编码错乱:
- 原本城市名里的
ł是标准UTF-8字符,对应两个原始字节0xC5、0x82 - 生成坏JSON的流程出了错:它把这两个原始字节直接当成了单字节的Latin1字符解析,把0xC5对应成了
Å、0x82对应成了不可见控制字符,之后又把这两个错配的字符按JSON规则生成了\u00c5、\u0082的转义序列拼在了一起。
核心还原逻辑
不管用什么工具实现,只要按三步操作就能拿到正确的可读字符:
- 先正常解析JSON,把转义序列解析成错配的中间字符串,比如拿到
WrocÅ\x82aw - 把这个中间字符串按Latin1编码重新转回原始字节,刚好就能拿到之前错配的那堆
b'Wroc\xc5\x82aw'字节 - 把这堆原始字节按UTF-8规则解码,就能得到正确的
Wrocław
大文件适配实现方案
考虑到你处理的是大型JSON,优先选内存占用极低的流式处理方案,不会因为文件太大触发内存溢出,下面是可直接运行的Python实现,无第三方依赖:
import json # 处理双重编码的字符串值 def fix_garbled_str(content): try: return content.encode("latin1").decode("utf-8") except (UnicodeEncodeError, UnicodeDecodeError): # 碰到没有双重编码的正常字符串,直接返回原内容,不做修改 return content # 逐行读写处理,避免一次性加载大文件 def process_large_json(input_path, output_path): with open(input_path, "r", encoding="utf-8") as fin, \ open(output_path, "w", encoding="utf-8") as fout: for line in fin: stripped_line = line.strip() if not stripped_line: fout.write(line) continue # 解析单行JSON值,对所有字符串类型的字段做修复 parsed = json.loads(stripped_line, object_hook=lambda obj: { key: fix_garbled_str(val) if isinstance(val, str) else val for key, val in obj.items() }) # 序列化时关闭ASCII转义,直接输出可读字符,不再生成新的\u转义 fout.write(json.dumps(parsed, ensure_ascii=False) + "\n") # 替换成你自己的文件路径运行即可 if __name__ == "__main__": process_large_json("input_bad.json", "output_good.json")
避坑提醒
- 不要直接用普通的JSON解析工具后就直接输出:普通解析只会把转义序列解析成错配的
Å和不可见控制字符,根本没法还原正确文字,必须在解析后加一道Latin1转UTF8的步骤。 - 输出JSON的时候必须关闭ASCII转义(对应Python里的
ensure_ascii=False),不然好不容易转好的可读字符,又会被重新编码成\uXXXX的转义序列,等于白忙活。 - 千万不要用在线的Unicode解码工具直接跑这串乱码,那些工具默认的解码逻辑没法识别双重编码的场景,输出还是错的乱码。
内容的提问来源于stack exchange,提问作者F.Hand
相关产品推荐
相关产品推荐

