Appearance
35|网络请求
程序与外部系统交互最常见的方式是 HTTP 请求。获取 API 数据、发送报告、调用 Webhook——这些都需要构造 HTTP 请求、处理响应、解析返回的数据。
Python 标准库的 urllib 可以发 HTTP 请求,但接口繁琐。第三方库 requests 是事实标准,API 设计直观,覆盖了绝大多数场景。
一、安装 requests
bash
pip install requests二、GET 请求
python
import requests
response = requests.get("https://api.example.com/users", timeout=10)
print(response.status_code) # 200
print(response.text) # 响应正文(字符串)
print(response.json()) # 响应正文解析为 JSON(如果内容是 JSON)timeout=10 设置超时时间(秒)。超时不能省——没有超时的请求可能永远卡住,导致程序挂起。
带查询参数:
python
params = {"page": 1, "limit": 10}
response = requests.get("https://api.example.com/users", params=params, timeout=10)
# 实际请求 URL: https://api.example.com/users?page=1&limit=10三、POST 请求
发送 JSON 数据:
python
payload = {"name": "Alice", "age": 25}
response = requests.post(
"https://api.example.com/users",
json=payload,
timeout=10,
)发送表单数据:
python
response = requests.post(
"https://api.example.com/users",
data={"name": "Alice", "age": 25},
timeout=10,
)json= 自动把字典序列化为 JSON 字符串,并设置 Content-Type: application/json。data= 发送表单编码数据。
四、响应处理
python
response = requests.get("https://api.example.com/users/1", timeout=10)
if response.status_code == 200:
data = response.json()
print(data["name"])
elif response.status_code == 404:
print("用户不存在")
else:
print(f"请求失败: {response.status_code}")raise_for_status() 自动检查状态码,非 2xx 时抛出异常:
python
response = requests.get("https://api.example.com/users/1", timeout=10)
response.raise_for_status() # 404 时抛出 HTTPError
data = response.json()常用状态码:
| 状态码 | 含义 |
|---|---|
| 200 | 成功 |
| 201 | 创建成功 |
| 400 | 请求参数错误 |
| 401 | 未认证 |
| 403 | 无权限 |
| 404 | 资源不存在 |
| 500 | 服务器内部错误 |
| 502 | 网关错误 |
| 503 | 服务不可用 |
五、请求头
python
headers = {
"Authorization": "Bearer token123",
"Accept": "application/json",
}
response = requests.get(
"https://api.example.com/users",
headers=headers,
timeout=10,
)Token 等敏感信息不要硬编码在代码里,从环境变量读取:
python
import os
token = os.environ.get("API_TOKEN")
headers = {"Authorization": f"Bearer {token}"}六、异常处理
网络请求可能遇到各种异常:
python
import requests
url = "https://api.example.com/users"
try:
response = requests.get(url, timeout=10)
response.raise_for_status()
data = response.json()
except requests.Timeout:
print("请求超时")
except requests.ConnectionError:
print("连接失败")
except requests.HTTPError as exc:
print(f"HTTP 错误: {exc.response.status_code}")
except requests.RequestException:
print("请求出错")异常继承关系:
RequestException
├── Timeout
├── ConnectionError
├── HTTPError
└── ...捕获 RequestException 可以处理所有 requests 相关的异常。
七、Session
多次请求同一个域名时,用 Session 复用 TCP 连接,提升性能:
python
session = requests.Session()
session.headers.update({"Authorization": "Bearer token123"})
response1 = session.get("https://api.example.com/users", timeout=10)
response2 = session.get("https://api.example.com/orders", timeout=10)Session 还会自动处理 cookie。
八、下载文件
python
response = requests.get("https://example.com/file.zip", stream=True, timeout=30)
response.raise_for_status()
with open("file.zip", "wb") as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)stream=True 不一次性加载整个响应到内存,iter_content() 分块读取。大文件下载必须用流式读取。
记忆锚点:requests.get()/post() 发请求;timeout 不能省;json= 自动序列化 JSON;raise_for_status() 检查状态码;Token 从环境变量读,不要硬编码;捕获 RequestException 处理网络异常;Session 复用连接;大文件用 stream=True 分块下载。