前言

这里只是是一本requests的简单修炼手册


一、概述

Requests 是 Python 中最流行的 HTTP 客户端库,提供简洁易用的 API 进行 HTTP 请求操作。核心特点包括:

  • 人性化设计:简洁直观的 API
  • 功能全面:支持 HTTP 所有方法、参数传递、认证等
  • 高效可靠:自动处理连接池、重定向等底层细节
  • 广泛兼容:完美支持 Python 2.7 和 3.5+
1
2
3
4
import requests

response = requests.get('https://api.example.com/data')
print(response.json()) # 直接获取JSON响应

二、核心请求方法

2.1 常用 HTTP 方法

1
2
3
4
5
6
requests.get(url, params=None, **kwargs)     # GET 请求
requests.post(url, data=None, json=None, **kwargs) # POST 请求
requests.put(url, data=None, **kwargs) # PUT 请求
requests.delete(url, **kwargs) # DELETE 请求
requests.head(url, **kwargs) # HEAD 请求
requests.patch(url, data=None, **kwargs) # PATCH 请求

2.2 基本 GET 请求

1
2
3
4
5
# 带查询参数
params = {'key1': 'value1', 'key2': 'value2'}
response = requests.get('https://httpbin.org/get', params=params)

print(response.url) # 查看实际请求URL: https://httpbin.org/get?key1=value1&key2=value2

三、请求参数处理

3.1 POST 数据格式

1
2
3
4
5
6
7
8
9
10
11
# 表单数据 (application/x-www-form-urlencoded)
form_data = {'username': 'admin', 'password': 'secret'}
response = requests.post('https://httpbin.org/post', data=form_data)

# JSON 数据 (application/json)
json_data = {'name': 'John', 'age': 30}
response = requests.post('https://httpbin.org/post', json=json_data)

# 文件上传 (multipart/form-data)
files = {'file': open('report.xlsx', 'rb')}
response = requests.post('https://httpbin.org/post', files=files)

3.2 自定义请求头

1
2
3
4
5
6
7
headers = {
'User-Agent': 'MyApp/1.0',
'Authorization': 'Bearer ACCESS_TOKEN',
'Accept': 'application/json'
}

response = requests.get('https://api.example.com', headers=headers)

四、响应处理

4.1 响应内容解析

1
2
3
4
5
6
7
8
response = requests.get('https://api.example.com/data')

print(response.status_code) # HTTP 状态码 (200, 404等)
print(response.text) # 响应文本 (自动解码)
print(response.content) # 原始二进制响应
print(response.json()) # 解析JSON响应 (dict/list)
print(response.headers) # 响应头 (字典形式)
print(response.cookies) # 服务器设置的cookies

4.2 响应编码处理

1
2
3
4
5
# 手动设置编码
response.encoding = 'utf-8'

# 自动检测编码
response.encoding = response.apparent_encoding

五、高级功能

5.1 会话管理 (Session)

1
2
3
4
5
6
7
8
9
# 创建会话对象 (自动保持cookies)
session = requests.Session()

# 登录保持会话
login_data = {'user': 'admin', 'pass': 'password'}
session.post('https://example.com/login', data=login_data)

# 后续请求自动携带cookies
response = session.get('https://example.com/dashboard')

5.2 超时控制

1
2
3
4
5
# 连接+读取总超时
requests.get('https://example.com', timeout=5)

# 分别设置连接和读取超时
requests.get('https://example.com', timeout=(3.05, 27))

5.3 代理设置

1
2
3
4
5
6
proxies = {
'http': 'http://10.10.1.10:3128',
'https': 'http://10.10.1.10:1080',
}

requests.get('https://example.com', proxies=proxies)

六、安全与认证

6.1 基本认证

1
2
3
4
5
from requests.auth import HTTPBasicAuth

response = requests.get(
'https://api.example.com',
auth=HTTPBasicAuth('username', 'password')

6.2 SSL 证书验证

1
2
3
4
5
# 禁用证书验证 (不推荐)
requests.get('https://example.com', verify=False)

# 使用自定义CA证书
requests.get('https://example.com', verify='/path/to/cert.pem')

七、错误处理

7.1 异常捕获

1
2
3
4
5
6
7
8
9
try:
response = requests.get('https://example.com', timeout=3)
response.raise_for_status() # 检查HTTP错误状态码
except requests.exceptions.Timeout:
print("请求超时")
except requests.exceptions.HTTPError as err:
print(f"HTTP错误: {err}")
except requests.exceptions.RequestException as err:
print(f"请求异常: {err}")

7.2 重试机制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry

retry_strategy = Retry(
total=3, # 最大重试次数
status_forcelist=[429, 500, 502, 503, 504], # 需要重试的状态码
method_whitelist=["GET", "POST"], # 需要重试的HTTP方法
backoff_factor=1 # 重试等待时间因子
)

adapter = HTTPAdapter(max_retries=retry_strategy)
session = requests.Session()
session.mount("https://", adapter)

response = session.get("https://example.com")

八、性能优化

8.1 流式下载大文件

1
2
3
4
5
6
7
url = "https://example.com/large-file.zip"

with requests.get(url, stream=True) as response:
response.raise_for_status()
with open("large-file.zip", "wb") as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)

8.2 连接复用

1
2
3
4
5
6
# 使用会话对象自动复用连接
session = requests.Session()

for _ in range(10):
response = session.get('https://api.example.com/data')
process_data(response.json())

九、最佳实践

  1. 总是检查状态码:使用 response.raise_for_status() 或手动检查
  2. 使用会话对象:对于多个请求到同一主机
  3. 设置合理超时:避免程序无限等待
  4. 处理编码问题:明确指定响应编码
  5. 关闭响应对象:使用 with 语句或手动 response.close()
  6. 限制重定向:设置 max_redirects 防止无限重定向
  7. 使用环境变量:管理敏感信息如 API 密钥
  8. 添加用户代理:设置合理的 User-Agent 头
  9. 日志记录:使用 logging 模块记录请求详情
  10. 异步请求:对于高并发使用 aiohttphttpx

十、实用技巧

10.1 调试请求

1
2
3
4
5
6
7
# 打印请求详情
import logging
logging.basicConfig(level=logging.DEBUG)

# 或者手动打印
print(response.request.headers)
print(response.request.body)

10.2 下载进度条

1
2
3
4
5
6
7
8
9
10
11
12
13
from tqdm import tqdm

url = "https://example.com/large-file.iso"
response = requests.get(url, stream=True)
total_size = int(response.headers.get('content-length', 0))

with open("large-file.iso", "wb") as f:
for chunk in tqdm(
response.iter_content(chunk_size=1024),
total=total_size//1024,
unit='KB'
):
f.write(chunk)