Skip to content

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/jsondata= 发送表单编码数据。

四、响应处理

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 分块下载。