response.json() 报错主因是服务器返回非合法json内容,如html错误页、空响应、4xx/5xx状态码未检查、编码异常或bom头干扰;须先校验status_code==200并用try/except捕获jsondecodeerror。

用 requests.get() 获取 JSON 接口数据时,为什么 response.json() 报错?
常见原因是接口返回非标准 JSON(比如含 BOM 头、HTML 错误页、空响应或 4xx/5xx 状态码却未检查)。直接调用 response.json() 会抛出 JSONDecodeError。
- 务必先检查
response.status_code == 200,再解析 - 对可能失败的请求加
try/except捕获requests.exceptions.RequestException和json.JSONDecodeError - 若接口返回带 BOM 的 UTF-8(如
b'\xef\xbb\xbf{...}'),response.json()仍可正常解析;但若手动读取response.content再解码,需用.decode('utf-8-sig')去 BOM
提取多层嵌套字段(如 data.items[0].user.profile.name)怎么避免 KeyError 或 IndexError?
硬写 res['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 然后调用 <code>safe_get(res, 'data', 'items', 0, 'user', 'profile', 'name')</code> - 不要依赖固定索引(如
[0])——先确认len(items) > 0,否则默认值更稳妥
遇到字段类型不一致(比如有时是 str,有时是 None 或 dict)怎么办?
真实接口常有“柔性结构”:同一字段在不同数据里类型不同(如 avatar 可能是 URL 字符串,也可能是 {"small": "...", "large": "..."})。硬类型断言会出问题。
- 用
isinstance(x, str)或isinstance(x, dict)显式判断分支逻辑 - 若需统一处理,提前归一化:比如把 avatar 转成字符串(
avatar_url = x if isinstance(x, str) else x.get('large', '') if isinstance(x, dict) else '') - 别用
or简写(如data.get('name') or 'N/A')——若字段值是空字符串或0,也会被误判为 False
批量请求多个分页接口并合并 JSON 数据,如何控制并发又不被封?
用 requests 同步发几十个请求既慢又容易触发风控。改用 concurrent.futures.ThreadPoolExecutor 是平衡点,但必须限速。
- 设置线程数 ≤ 3~5(多数公开 API 限制 QPS 在 1~10)
- 每次请求后加
time.sleep(0.1)(比无延迟稳得多) - 用
session = requests.Session()复用连接,提升吞吐 - 注意:某些接口要求带
User-Agent或Authorization,漏掉会导致 403;headers 必须在每个session.get()中传入,不能只设在 session 上(部分服务不识别 session 级 headers)
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











