json解析失败往往因非json响应、bom/垃圾字符、大文件内存溢出或格式残缺所致,须先验状态码与content-type,清洗前置字符,优先用ijson流式解析,结合e.lineno/e.colno精准定位。

先确认是不是真JSON数据,还是HTTP错误页混进来了
很多“大型JSON文件解析失败”根本不是JSON本身的问题,而是你拿到的根本不是JSON。比如API返回404时送你一个HTML错误页,或者限流时返回纯文本提示,response.text一打印全是或Rate limit exceeded——这种内容传给json.loads()必然报JSONDecodeError: Expecting value: line 1 column 1 (char 0)。
- 必须在解析前检查
response.status_code,2xx之外的响应一律不走JSON路径 - 打印
response.headers.get('Content-Type'),如果不是application/json(或text/json),别急着解析 - 用
response.text[:200]快速看前两百字符,肉眼识别有没有、<code>ERROR、Over quota这类关键词
文件开头有BOM或前置垃圾字符?先清洗再加载
Windows生成的UTF-8文件常带BOM头\ufeff,某些API响应开头还有)]}'\n(如老版Google API),这些字符会让json.loads()直接在第0位报错。
- 读文件时用
open(..., encoding='utf-8-sig')自动剥离BOM,比手动.lstrip('\ufeff')更可靠 - 如果是网络响应,先做字符串清洗:
s = response.text.strip(),再删前置垃圾:s = s.lstrip(")]}'\n") - 避免用
s.replace("'", '"')粗暴替换单引号——嵌套单引号会炸,只在确认无嵌套时才用
大文件解析卡死或内存爆掉?别用json.load()硬扛
用json.load(f)加载几个GB的JSON文件,Python会把整个文件读进内存再解析,不仅慢,还容易触发MemoryError或让JSONDecodeError定位失真(pos偏移算不准)。
- 优先改用流式工具:安装
pip install ijson,用ijson.parse(f)逐个事件读取,不加载全文 - 如果必须全量加载,先用
head -c 10000 big.json | python -m json.tool验证开头是否合法,排除截断问题 - 别依赖
e.pos直接对应编辑器位置——大文件里制表符、\r\n、编码不一致都会让列号偏移,用e.lineno和e.colno更靠谱
报错说“Expecting ','”或“Expecting property name”?大概率是格式残缺
这类错误在大文件里特别隐蔽:可能是传输中断导致JSON截断,也可能是日志系统拼接时漏了逗号或括号。光看报错行没用,得结合上下文。
- 用
e.pos定位后,取前后50字符打印:print(repr(data[max(0, e.pos-50):e.pos+50])),比只看行号更能暴露真实问题 - 检查是否用了尾逗号(
{"a": 1,})或单引号({'a': 1})——标准JSON不认,但json5.loads()能吃 - 如果数据源可控,加一层预校验:用
python -m json.tool input.json > /dev/null命令行验证,失败就别进Python流程
JSONDecodeError在最意想不到的位置冒出来。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











