response.json() 报错主因是服务器返回非合法JSON内容,如HTML错误页、空响应、4xx/5xx状态码未检查、编码异常或BOM头干扰;须先校验status_code==200并用try/except捕获JSONDecodeError。
用
获取 JSON 接口数据时,为什么
报错?
常见原因是接口返回非标准 JSON(比如含 BOM 头、HTML 错误页、空响应或 4xx/5xx 状态码却未检查)。直接调用
会抛出
。
务必先检查
,再解析
对可能失败的请求加
捕获
和
若接口返回带 BOM 的 UTF-8(如
),
仍可正常解析;但若手动读取
再解码,需用
去 BOM
提取多层嵌套字段(如
)怎么避免
或
?
硬写
极易崩。推荐用安全访问模式:
用
链式调用:
更清晰的做法是封装一个安全取值函数,例如:
然后调用
不要依赖固定索引(如
)——先确认
,否则默认值更稳妥
遇到字段类型不一致(比如有时是
,有时是
或
)怎么办?
真实接口常有“柔性结构”:同一字段在不同数据里类型不同(如
可能是 URL 字符串,也可能是
)。硬类型断言会出问题。
Find JSON Path Online
Easily find JSON paths within JSON objects using our intuitive Json Path Finder
下载
用
或
显式判断分支逻辑
若需统一处理,提前归一化:比如把 avatar 转成字符串(
)
别用
简写(如
)——若字段值是空字符串或
,也会被误判为 False
批量请求多个分页接口并合并 JSON 数据,如何控制并发又不被封?
用
同步发几十个请求既慢又容易触发风控。改用
是平衡点,但必须限速。
立即学习
“
Python免费学习笔记(深入)
”;
设置线程数 ≤ 3~5(多数公开 API 限制 QPS 在 1~10)
每次请求后加
(比无延迟稳得多)
用
复用连接,提升吞吐
注意:某些接口要求带
或
,漏掉会导致 403;headers 必须在每个
中传入,不能只设在 session 上(部分服务不识别 session 级 headers)
字段嵌套越深、接口越不稳定,越要放弃“一口气取到底”的写法。宁可多写两行判断,也不要让整个流程因一个空字段中断。
requests.get()response.json()response.json()JSONDecodeErrorresponse.status_code == 200try/exceptrequests.exceptions.RequestExceptionjson.JSONDecodeErrorb'\xef\xbb\xbf{...}'response.json()response.content.decode('utf-8-sig')data.items[0].user.profile.nameKeyErrorIndexErrorres['data']['items'][0]['user']['profile']['name']dict.get()res.get('data', {}).get('items', [{}])[0].get('user', {}).get('profile', {}).get('name')def safe_get(obj, *keys, default=None):
for k in keys:
if isinstance(obj, dict) and k in obj:
obj = obj[k]
elif isinstance(obj, list) and isinstance(k, int) and 0 <= k < len(obj):
obj = obj[k]
else:
return default
return objsafe_get(res, 'data', 'items', 0, 'user', 'profile', 'name')[0]len(items) > 0strNonedictavatar{"small": "...", "large": "..."}isinstance(x, str)isinstance(x, dict)avatar_url = x if isinstance(x, str) else x.get('large', '') if isinstance(x, dict) else ''ordata.get('name') or 'N/A'0requestsconcurrent.futures.ThreadPoolExecutortime.sleep(0.1)session = requests.Session()User-AgentAuthorizationsession.get()