Python请求库:HTTP客户端完全指南
什么是Python请求库?
Requests是一个优雅而简单的Python HTTP库,为人类设计。它允许你以极其简单的方式发送HTTP/1.1请求,不需要手动添加查询字符串到URL,也不需要表单编码POST数据。Requests是Python中最受欢迎的第三方库之一,每天被数以万计的应用程序使用。
为什么选择Requests?
优势 | 说明 |
---|---|
简单易用 | API设计直观,学习曲线平缓 |
功能全面 | 支持HTTP所有基本方法、会话、认证等 |
自动处理 | 自动解码内容、处理重定向、超时等 |
社区支持 | 文档完善,社区活跃,问题容易解决 |
兼容性好 | 支持Python 2.7和3.5+ |
安装Requests
使用pip安装Requests:
pip install requests
这段命令使用Python的包管理工具pip来安装Requests库及其依赖项
基本HTTP请求
主要HTTP方法
方法 | Requests函数 | 描述 |
---|---|---|
GET | requests.get() | 获取资源 |
POST | requests.post() | 创建资源 |
PUT | requests.put() | 更新资源 |
DELETE | requests.delete() | 删除资源 |
HEAD | requests.head() | 获取头部信息 |
OPTIONS | requests.options() | 获取支持的HTTP方法 |
GET请求示例
import requests
# 基本GET请求
response = requests.get('https://api.github.com')
print(response.status_code) # 200
print(response.text) # 响应内容
# 带参数的GET请求
params = {'key1': 'value1', 'key2': 'value2'}
response = requests.get('https://httpbin.org/get', params=params)
print(response.url) # https://httpbin.org/get?key1=value1&key2=value2
代码解释:
requests.get()
发送GET请求status_code
属性获取HTTP状态码text
属性获取响应内容params
参数自动编码为URL查询字符串
POST请求示例
import requests
# 表单数据POST
data = {'key1': 'value1', 'key2': 'value2'}
response = requests.post('https://httpbin.org/post', data=data)
print(response.json()) # 解析JSON响应
# JSON数据POST
json_data = {'name': 'John', 'age': 30}
response = requests.post('https://httpbin.org/post', json=json_data)
print(response.json())
代码解释:
requests.post()
发送POST请求data
参数发送表单编码数据json
参数自动编码为JSON格式json()
方法解析JSON响应
响应处理
响应对象属性
属性 | 描述 | 示例 |
---|---|---|
status_code | HTTP状态码 | 200 |
text | 响应内容(字符串) | '{"key":"value"}' |
content | 响应内容(字节) | b'{"key":"value"}' |
json() | 解析JSON响应 | {'key': 'value'} |
headers | 响应头 | {'Content-Type': 'application/json'} |
cookies | cookies字典 | {'session_id': '12345'} |
url | 最终请求URL | 'https://example.com' |
响应内容处理
import requests
response = requests.get('https://api.github.com/events')
# 检查请求是否成功
if response.status_code == 200:
# 解析JSON响应
data = response.json()
print(f"Received {len(data)} events")
# 获取响应头
print(f"Content-Type: {response.headers['content-type']}")
# 获取编码
print(f"Encoding: {response.encoding}")
# 二进制内容
image_response = requests.get('https://example.com/image.jpg')
with open('image.jpg', 'wb') as f:
f.write(image_response.content)
高级功能
会话对象
import requests
# 创建会话
session = requests.Session()
# 设置公共参数
session.params = {'api_key': 'my_api_key'}
# 使用会话发送请求
response = session.get('https://api.example.com/data')
print(response.json())
# 会话会自动处理cookies
response = session.post('https://api.example.com/login', data={'user': 'admin', 'pass': 'secret'})
print(session.cookies.get_dict())
代码解释:
Session()
创建持久会话- 会话可以保持参数、cookies、头信息等
- 适合需要多次请求同一网站的场景
超时设置
import requests
try:
# 设置连接超时和读取超时(秒)
response = requests.get('https://api.example.com', timeout=(3.05, 27))
except requests.exceptions.Timeout:
print("请求超时")
except requests.exceptions.RequestException as e:
print(f"请求错误: {e}")
重试机制
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
# 创建会话
session = requests.Session()
# 配置重试策略
retries = Retry(
total=3, # 最大重试次数
backoff_factor=1, # 重试等待时间因子
status_forcelist=[500, 502, 503, 504] # 需要重试的状态码
)
# 挂载适配器
session.mount('http://', HTTPAdapter(max_retries=retries))
session.mount('https://', HTTPAdapter(max_retries=retries))
# 使用会话
response = session.get('https://api.example.com/unstable')
认证与安全
基本认证
import requests
from requests.auth import HTTPBasicAuth
response = requests.get(
'https://api.example.com/protected',
auth=HTTPBasicAuth('username', 'password')
)
OAuth认证
import requests
headers = {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
}
response = requests.get('https://api.example.com/user', headers=headers)
SSL证书验证
import requests
# 验证SSL证书(默认)
response = requests.get('https://example.com')
# 禁用SSL验证(不推荐)
response = requests.get('https://example.com', verify=False)
# 使用自定义CA证书
response = requests.get('https://example.com', verify='/path/to/cert.pem')
代理设置
import requests
proxies = {
'http': 'http://10.10.1.10:3128',
'https': 'http://10.10.1.10:1080',
}
response = requests.get('http://example.com', proxies=proxies)
# 需要认证的代理
proxies = {
'http': 'http://user:pass@10.10.1.10:3128/',
}
文件上传
import requests
# 上传单个文件
files = {'file': open('report.xls', 'rb')}
response = requests.post('https://httpbin.org/post', files=files)
# 上传多个文件
files = [
('images', ('foo.png', open('foo.png', 'rb'), 'image/png')),
('images', ('bar.png', open('bar.png', 'rb'), 'image/png'))
]
response = requests.post('https://httpbin.org/post', files=files)
错误处理
常见异常
异常 | 描述 |
---|---|
RequestException | 所有requests异常的基类 |
ConnectionError | 连接错误 |
HTTPError | HTTP错误响应(4xx, 5xx) |
Timeout | 请求超时 |
TooManyRedirects | 重定向次数过多 |
SSLError | SSL证书错误 |
错误处理示例
import requests
from requests.exceptions import RequestException
try:
response = requests.get('https://api.example.com', timeout=5)
response.raise_for_status() # 如果状态码不是200,抛出HTTPError
data = response.json()
except RequestException as e:
print(f"请求失败: {e}")
性能优化
连接池
import requests
# 使用会话保持连接
session = requests.Session()
for i in range(10):
# 复用TCP连接
response = session.get('https://api.example.com/data')
print(response.json())
流式请求
import requests
# 流式下载大文件
response = requests.get('https://example.com/large_file', stream=True)
with open('large_file', 'wb') as f:
for chunk in response.iter_content(chunk_size=8192):
if chunk: # 过滤keep-alive新块
f.write(chunk)
实用示例
API客户端封装
import requests
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_user(self, user_id):
url = f"{self.base_url}/users/{user_id}"
response = self.session.get(url)
response.raise_for_status()
return response.json()
def create_user(self, user_data):
url = f"{self.base_url}/users"
response = self.session.post(url, json=user_data)
response.raise_for_status()
return response.json()
# 使用客户端
client = APIClient('https://api.example.com', 'my_api_key')
user = client.get_user(123)
网页抓取
import requests
from bs4 import BeautifulSoup
response = requests.get('https://example.com')
soup = BeautifulSoup(response.text, 'html.parser')
# 提取所有链接
for link in soup.find_all('a'):
print(link.get('href'))
总结
Python Requests库是现代Web开发的必备工具,它简化了HTTP通信的复杂性,让开发者可以专注于业务逻辑而不是底层协议细节。
关键要点
- 简单直观:API设计人性化,易于学习和使用
- 功能丰富:支持各种HTTP方法、认证、会话、代理等
- 高效可靠:自动处理连接池、重定向、内容解码等
- 社区支持:文档完善,问题容易解决
最佳实践
- 总是检查响应状态码或使用
raise_for_status()
- 使用会话(Session)进行多次请求
- 为生产环境设置合理的超时
- 处理可能的异常情况
- 考虑使用连接池提高性能
进一步学习
- 官方文档:https://docs.python-requests.org/
- 高级用法:https://requests.readthedocs.io/en/master/user/advanced/
- 社区资源:https://realpython.com/python-requests/