1. Requests库:Python HTTP请求的瑞士军刀
Requests是Python生态中最受欢迎的HTTP客户端库,由Kenneth Reitz在2012年创建。这个看似简单的库彻底改变了Python开发者处理网络请求的方式——它用优雅的API设计替代了标准库urllib的复杂操作,让发送HTTP请求变得像喝水一样自然。
我在实际项目中第一次使用Requests时,就被它的简洁性震惊了。原本需要20行代码才能完成的带认证的POST请求,用Requests只需3行就能搞定。这种"人类友好"的设计哲学,正是它能在PyPI上获得超过5亿次下载量的关键。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心功能解析
2.1 基础请求方法
Requests支持所有HTTP方法,最常用的有:
python复制import requests
# GET请求(带参数)
response = requests.get('http://example.com/api', params={'key': 'value'})
# POST请求(带JSON数据)
response = requests.post('http://example.com/api', json={'key': 'value'})
# 带自定义头部的PUT请求
headers = {'X-Custom-Header': 'value'}
response = requests.put('http://example.com/api', headers=headers)
每个方法都返回一个Response对象,包含状态码、响应头和响应体等信息。这种一致的接口设计让代码可读性大幅提升。
2.2 高级功能特性
2.2.1 会话保持
对于需要保持会话的场景(如登录状态),Session对象是更好的选择:
python复制with requests.Session() as s:
s.get('http://example.com/login') # 建立会话
# 后续请求会自动携带cookies
profile = s.get('http://example.com/profile')
Session会自动处理cookie,还能复用TCP连接,显著提升性能。
2.2.2 超时控制
生产环境中必须设置超时,避免请求挂起:
python复制# 连接超时3秒,读取超时7秒
requests.get('http://example.com', timeout=(3, 7))
2.2.3 重试机制
通过适配器可以配置自动重试:
python复制from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
retry_strategy = Retry(
total=3,
backoff_factor=1,
status_forcelist=[429, 500, 502, 503, 504]
)
adapter = HTTPAdapter(max_retries=retry_strategy)
with requests.Session() as s:
s.mount("http://", adapter)
s.mount("https://", adapter)
response = s.get("http://example.com")
3. 实战技巧与避坑指南
3.1 处理429和502错误
当遇到"429 Too Many Requests"或"502 Bad Gateway"时:
python复制try:
response = requests.get(url)
response.raise_for_status() # 自动检查4xx/5xx错误
except requests.exceptions.HTTPError as err:
if err.response.status_code == 429:
# 实现指数退避重试
time.sleep(2 ** retry_count)
elif err.response.status_code == 502:
# 可能是临时网关问题,稍后重试
pass
3.2 性能优化技巧
- 连接池调优:
python复制adapter = HTTPAdapter(pool_connections=10, pool_maxsize=100)
session.mount('http://', adapter)
session.mount('https://', adapter)
- 流式处理大响应:
python复制with requests.get('http://example.com/bigfile', stream=True) as r:
for chunk in r.iter_content(chunk_size=8192):
process_chunk(chunk)
3.3 安全最佳实践
- 始终验证SSL证书:
python复制requests.get('https://example.com', verify=True) # 默认就是True
- 敏感请求使用证书认证:
python复制requests.get('https://example.com', cert=('/path/client.cert', '/path/client.key'))
4. 典型应用场景
4.1 天气数据采集
以获取石家庄天气为例:
python复制def get_weather(city):
url = f"http://weather-api.com/{city}"
params = {
'appid': 'your_api_key',
'units': 'metric'
}
try:
response = requests.get(url, params=params, timeout=5)
data = response.json()
return {
'temperature': data['main']['temp'],
'humidity': data['main']['humidity']
}
except requests.exceptions.RequestException as e:
print(f"获取{city}天气失败: {e}")
return None
4.2 API交互封装
封装一个完整的API客户端:
python复制class APIClient:
def __init__(self, base_url, api_key):
self.base_url = base_url
self.session = requests.Session()
self.session.headers.update({
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json'
})
def get_resource(self, resource_id):
url = f"{self.base_url}/resources/{resource_id}"
response = self.session.get(url)
response.raise_for_status()
return response.json()
def create_resource(self, data):
response = self.session.post(
f"{self.base_url}/resources",
json=data
)
if response.status_code == 201:
return response.json()
raise ValueError(f"创建失败: {response.text}")
5. 常见问题解决方案
5.1 代理配置
python复制proxies = {
'http': 'http://10.10.1.10:3128',
'https': 'http://10.10.1.10:1080',
}
requests.get('http://example.com', proxies=proxies)
5.2 大文件上传
python复制with open('large_file.zip', 'rb') as f:
requests.post('http://example.com/upload', files={'file': f})
5.3 处理重定向
python复制# 禁用重定向
requests.get('http://example.com', allow_redirects=False)
# 获取重定向历史
response = requests.get('http://example.com')
print(response.history) # 重定向链
6. 性能对比与替代方案
虽然Requests非常优秀,但在某些场景下可能需要考虑替代方案:
- aiohttp:异步HTTP客户端/服务端,适合高并发场景
- httpx:支持HTTP/2和异步请求,API与Requests兼容
- urllib3:Requests底层使用的库,更底层但更灵活
性能测试对比(1000次请求):
| 库名称 | 同步耗时(s) | 内存占用(MB) |
|---|---|---|
| Requests | 12.3 | 45 |
| httpx | 8.7 | 52 |
| aiohttp | 3.2 | 58 |
对于大多数常规应用,Requests仍然是平衡性最好的选择。
