使用 requests 发送 HTTP 请求
约 1309 字大约 4 分钟
2026-05-10
requests 是 Python 中最常用的同步 HTTP 客户端库,适合调用 API、下载文件、写简单爬虫。
- 安装
- GET 请求
- query 参数
- POST JSON
- 1所有 requests 调用都传 timeout=(推荐 (3, 10) 分别控连接和读取)—— 不传超时是最大反模式。
- 2查询参数永远用 params= 字典,POST JSON 永远用 json= 字典(自动设 Content-Type)。
- 3response.raise_for_status() 把 4xx/5xx 转成异常,避免 if status == 200 散落各处。
- 4大文件下载用 stream=True + iter_content(chunk_size=8192),不要一次性 .content。
- 5同域多次请求用 requests.Session():复用连接池和 TLS 握手,速度快很多。
requests 是 Python 中最常用的同步 HTTP 客户端库,适合调用 API、下载文件、写简单爬虫。
安装
pip install requestsGET 请求
import requests
response = requests.get('https://httpbin.org/get')
print(response.status_code)
print(response.text)query 参数
使用 params 传递 query 参数:
response = requests.get(
'https://httpbin.org/get',
params={'keyword': 'python', 'page': 1},
)
print(response.url)不要手动拼接复杂 query。
POST JSON
response = requests.post(
'https://httpbin.org/post',
json={'name': 'Alice', 'age': 18},
)
print(response.json())使用 json= 时,requests 会自动序列化 JSON,并设置合适的 Content-Type。
POST Form
response = requests.post(
'https://httpbin.org/post',
data={'username': 'alice', 'password': 'secret'},
)data= 默认适合表单请求。
Header
headers = {
'Authorization': 'Bearer token',
'User-Agent': 'my-python-client/1.0',
}
response = requests.get('https://httpbin.org/headers', headers=headers)超时
一定要设置超时。
response = requests.get('https://httpbin.org/get', timeout=5)也可以区分连接超时和读取超时:
response = requests.get(url, timeout=(3, 10))响应内容
print(response.status_code)
print(response.headers)
print(response.text)
print(response.content)
print(response.json())text:解码后的字符串content:原始 bytesjson():把响应解析为 JSON
raise_for_status
response = requests.get(url, timeout=5)
response.raise_for_status()
data = response.json()如果状态码是 4xx 或 5xx,raise_for_status() 会抛出 HTTPError。
文件下载
大文件应使用流式下载:
with requests.get(url, stream=True, timeout=30) as response:
response.raise_for_status()
with open('file.bin', 'wb') as f:
for chunk in response.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)文件上传
with open('avatar.png', 'rb') as f:
response = requests.post(
'https://httpbin.org/post',
files={'file': f},
timeout=10,
)常见异常
import requests
try:
response = requests.get(url, timeout=5)
response.raise_for_status()
data = response.json()
except requests.Timeout:
print('请求超时')
except requests.ConnectionError:
print('连接失败')
except requests.HTTPError as exc:
print(f'HTTP 错误:{exc}')
except ValueError:
print('响应不是合法 JSON')一个更接近日常项目的例子
实际项目里,我们通常不会只打印 response.text,而是要拿到 JSON 数据,再处理其中字段。
import requests
url = 'https://httpbin.org/json'
try:
response = requests.get(url, timeout=5)
response.raise_for_status()
data = response.json()
except requests.Timeout:
print('请求超时,请稍后再试')
except requests.ConnectionError:
print('网络连接失败')
except requests.HTTPError as exc:
print(f'服务器返回错误状态码:{exc}')
except ValueError:
print('服务器返回的不是 JSON')
else:
slideshow = data.get('slideshow', {})
print(slideshow.get('title'))这个例子比最短写法长,但更适合真实代码,因为它把几类常见失败分开处理了。
params、json、data 怎么选
这三个参数很常用,初学者可以先记住下面这张表:
| 参数 | 放在哪里 | 常见场景 |
|---|---|---|
params= | URL query string | 搜索、分页、筛选 |
json= | 请求体 JSON | 调用 JSON API |
data= | 请求体表单 | 传统表单提交 |
示例:
# GET /users?page=1&keyword=alice
requests.get(url, params={'page': 1, 'keyword': 'alice'})
# POST JSON body: {"name": "Alice"}
requests.post(url, json={'name': 'Alice'})
# POST form body: username=alice&password=secret
requests.post(url, data={'username': 'alice', 'password': 'secret'})不要为了省事手动拼复杂 URL,尤其当参数里有中文、空格、&、? 这类字符时,很容易拼错。
检查响应时看什么
拿到 response 后,建议按这个顺序看:
print(response.status_code) # 状态码
print(response.headers.get('Content-Type'))
print(response.url) # 最终请求 URL
print(response.text[:500]) # 先看前 500 个字符如果确认是 JSON,再调用:
data = response.json()很多接口报错时返回的并不是你期待的数据结构,而是类似这样的 JSON:
{
"error": "invalid_token",
"message": "token expired"
}所以不要默认 data['items'] 一定存在。更稳一点的写法是:
items = data.get('items', [])
for item in items:
print(item)写一个小函数复用请求逻辑
当同一个项目里要请求多个接口时,可以先抽一个简单函数:
import requests
BASE_URL = 'https://api.example.com'
def get_json(path, params=None):
url = BASE_URL + path
response = requests.get(url, params=params, timeout=5)
response.raise_for_status()
return response.json()
users = get_json('/users', params={'page': 1})
print(users)这还不是完整 API Client,但已经比到处复制 requests.get(...).json() 更好。后面如果要统一加 Token、日志、重试,也更容易改。
初学者常见坑
| 坑 | 说明 | 更好的做法 |
|---|---|---|
| 不设置 timeout | 服务卡住时程序可能一直等 | 每个请求都设置 timeout |
直接 .json() | 响应可能不是 JSON | 先检查状态码和内容类型 |
| 手动拼 query | 中文和特殊字符容易出错 | 使用 params= |
| 忽略状态码 | 404/500 也继续当成功处理 | 使用 raise_for_status() |
| 把 Token 写死在代码里 | 容易泄漏 | 从环境变量或配置读取 |
总结
requests 简洁易用,但要养成几个习惯:使用 params,设置 timeout,调用 raise_for_status(),捕获常见异常,大文件使用流式下载。
- `params=` 用于 URL 查询参数,`json=` 用于 JSON 请求体,`data=` 用于表单请求体。
- 真实项目里要设置 timeout、检查状态码、处理 JSON 解析失败和连接异常。
- 当请求逻辑重复出现时,先抽成函数,再逐步演化成 API Client。
版权所有
版权归属:Shuo Liu
