JSONDecodeError 是 Python json 模块因输入非合法 JSON 格式(如缺引号、多逗号、返回 HTML 等)抛出的异常;需通过 e.lineno/e.colno 定位错误位置,优先校验数据来源而非仅容错解析。

JSONDecodeError 是什么,为什么它总在读文件或调用 API 后冒出来
JSONDecodeError 是 Python json 模块抛出的异常,说明传给 json.loads() 或 json.load() 的字符串/文件内容**不是合法 JSON 格式**。它不是编码问题(比如 UTF-8 乱码),而是语法层面错误:缺引号、多逗号、用单引号代替双引号、尾部有注释、返回了 HTML 页面(如 404 错误页)却当成 JSON 解析等。
常见触发场景:
- 用
requests.get(url).text直接解析响应,但服务端返回了502 Bad Gateway的 HTML - 读取本地
.json文件时,编辑器自动加了 BOM 或保存为 UTF-8 with BOM - 前端拼接 JSON 字符串时漏了转义,比如值里含换行或未闭合的双引号
- 日志中复制了一段“看着像 JSON”的结构,实际是 Python dict 字面量(用了单引号或
None/True)
怎么快速定位具体哪一行、哪个字符出错
JSONDecodeError 实例自带 msg、lineno、colno 属性,别只打印 str(e) —— 那只会显示“Expecting property name enclosed in double quotes”,没用。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 捕获异常后,用
e.lineno和e.colno定位位置,再切片打印上下文:try: data = json.loads(text) except json.JSONDecodeError as e: print(f"Syntax error at line {e.lineno}, column {e.colno}") # 打印出错行附近 2 行 lines = text.splitlines() start = max(0, e.lineno - 3) for i in range(start, min(len(lines), e.lineno + 2)): marker = "→" if i == e.lineno - 1 else " " print(f"{marker} {i+1:2d} | {lines[i]}") - 对响应体做初步检查:
response.text.strip()[:100]看开头是不是{或[;如果是/code> 或 <code>,直接放弃解析 - 用在线工具(如 jsonlint.com)粘贴原始字符串验证,但注意脱敏敏感字段
绕过语法错误的几种务实做法(不推荐长期用)
有些场景你无法控制上游数据格式(比如爬虫、遗留系统),需要容错处理。但要注意:这些方法会掩盖真实问题,仅用于临时兜底。
可选方案:
- 用
ast.literal_eval()尝试解析类 JSON 的 Python 字面量(支持单引号、None、True):import ast try: data = json.loads(text) except json.JSONDecodeError: try: data = ast.literal_eval(text) # 仅限安全字符串,不含函数调用 except (ValueError, SyntaxError): raise ValueError("Not valid JSON nor Python literal") - 预处理字符串:删 BOM(
text.encode().decode('utf-8-sig'))、替换单引号为双引号(慎用!可能破坏字符串内引号)、移除尾部逗号(需正则谨慎匹配) - 用
json5库(pip install json5)替代原生json,它支持注释、单引号、尾逗号:import json5 data = json5.loads(text) # 更宽容,但非标准
真正该做的:从源头加固输入校验
依赖容错是下策。稳定系统应该在解析前就拒绝非法输入。
关键动作:
- HTTP 请求后,先检查
response.status_code == 200且response.headers.get('content-type', '').startswith('application/json') - 读文件时,用
encoding='utf-8'显式指定,并加errors='strict'防止静默解码失败 - 写 JSON 时统一用
json.dump(obj, f, ensure_ascii=False, indent=2),避免手动拼接 - CI 流程中加入 JSON Schema 校验(用
jsonschema库),比运行时异常更早发现问题
最常被忽略的一点:很多错误根本不是 JSON 解析问题,而是你拿到的压根就不是 JSON —— 先确认来源,再调试语法。


















