第 5 章 · 响应详解
本章目标:掌握响应状态码检查、JSON 解析、二进制处理和流式响应的完整用法。
5.1 状态码检查
HTTP 状态码表示请求处理结果:
| 范围 | 含义 | 示例 |
|---|---|---|
| 2xx | 成功 | 200 OK, 201 Created |
| 3xx | 重定向 | 301 Moved, 304 Not Modified |
| 4xx | 客户端错误 | 400 Bad Request, 404 Not Found |
| 5xx | 服务端错误 | 500 Internal Server Error |
python
import requests
resp = requests.get('https://httpbin.org/status/404')
# 方式一:手动检查
if resp.status_code == 200:
print('成功')
elif resp.status_code == 404:
print('未找到')
else:
print(f'其他状态: {resp.status_code}')
# 方式二:is_success 属性(2xx 返回 True)
if resp.is_success:
print('成功')
else:
print(f'失败: {resp.status_code}')
# 方式三:raise_for_status()(推荐,失败时抛异常)
resp.raise_for_status() # 如果状态码 >= 400,抛出 HTTPError5.2 JSON 响应处理
python
import requests
import json
resp = requests.get('https://api.github.com/users/octocat')
# 解析 JSON
data = resp.json()
print(data['name'])
# 检查是否为 JSON 响应
if resp.headers.get('Content-Type', '').startswith('application/json'):
data = resp.json()
else:
print('非 JSON 响应:', resp.text[:100])
# 处理 JSON 解析错误
try:
data = resp.json()
except requests.exceptions.JSONDecodeError as e:
print(f'JSON 解析失败: {e}')
print('原始响应:', resp.text[:200])5.3 二进制响应处理
适用于图片、文件、音频等:
python
import requests
# 下载图片
resp = requests.get('https://httpbin.org/image/png')
# 保存为文件
with open('download.png', 'wb') as f:
f.write(resp.content)
# 处理内存中的二进制数据
image_data = resp.content
# 可传递给 PIL、cv2 等库处理5.4 流式响应
处理大文件时使用 stream=True,避免一次性加载到内存:
python
import requests
# 流式下载大文件
with requests.get('https://httpbin.org/stream/20', stream=True) as resp:
resp.raise_for_status()
# 逐步读取内容
for line in resp.iter_lines():
if line:
print(line.decode('utf-8'))
# 下载大文件到磁盘
url = 'https://httpbin.org/drip?numbytes=500000&delay=1'
with requests.get(url, stream=True) as resp:
resp.raise_for_status()
total = int(resp.headers.get('content-length', 0))
with open('large_file.bin', 'wb') as f:
for chunk in resp.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)
# 可选:显示进度
# print(f'\r下载: {f.tell()}/{total}', end='')iter_content() 和 iter_lines() 是流式处理的关键方法。
5.5 响应超时
python
import requests
# 设置超时(秒)
try:
resp = requests.get('https://httpbin.org/delay/5', timeout=3)
except requests.exceptions.Timeout:
print('请求超时')
# 分别设置连接超时和读取超时
resp = requests.get(url, timeout=(5, 10)) # (connect_timeout, read_timeout)
# httpx 等效写法
import httpx
client = httpx.Client(timeout=10.0)
resp = client.get(url)5.6 本章小结
- 使用
resp.status_code或resp.is_success检查状态; resp.raise_for_status()在失败时抛出异常(推荐);- 二进制数据用
.content,JSON 用.json(); - 大文件用
stream=True+iter_content()流式处理; - 始终设置合理的超时时间。
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. resp.raise_for_status() 在什么情况下会抛出异常?
2. 流式响应 stream=True 的主要优势是?
3. timeout 参数设置为 (5, 10) 表示?
4. 处理二进制响应(如图片)应使用哪个属性?
🛠️ 动手实践
- 向 httpbin 发送请求获取 404 状态,分别用三种方式检查状态码。
- 流式下载一个 1MB 以上的文件,记录耗时和内存使用。
- 设置 2 秒超时,向慢速服务器发送请求,捕获 Timeout 异常。