requests
是 Python 中最受欢迎的 HTTP 客户端库之一,其源码设计优雅且模块化,适合学习优秀的 Python 项目架构。以下是对 requests
库的 核心源码解析,涵盖关键模块、设计模式和实现细节。
源码结构概览
requests
的源码主要分为以下几个核心模块:
requests/ ├── __init__.py # 暴露主要 API(如 get, post) ├── api.py # 实现请求方法(get/post/put/delete) ├── sessions.py # Session 类(核心请求逻辑) ├── models.py # Request/Response 对象模型 ├── adapters.py # HTTP 适配器(默认用 urllib3) ├── cookies.py # Cookie 处理 ├── utils.py # 工具函数(如 URL 编码) └── exceptions.py # 异常类
核心模块解析
1 sessions.py
(核心请求逻辑)
Session
类是 requests
的核心,负责:
-
维护 连接池(通过
urllib3
) -
处理 Cookies、Headers、代理 等全局配置
-
提供
request()
方法发送请求
关键代码:
class Session(SessionRedirectMixin): def __init__(self): self.headers = default_headers() # 默认请求头 self.auth = None # 认证信息 self.proxies = {} # 代理配置 self.adapters = OrderedDict() # HTTP 适配器(默认 urllib3) def request(self, method, url, **kwargs): # 1. 合并全局配置(如 headers/cookies)和局部配置 req = Request(method=method, url=url, headers=headers) prep = self.prepare_request(req) # 预处理请求 # 2. 选择适配器(默认 HTTP/HTTPS 分别对应不同适配器) adapter = self.get_adapter(url=url) # 3. 发送请求(通过 urllib3) resp = adapter.send(prep, **send_kwargs) return resp
2 adapters.py
(HTTP 适配器)
HTTPAdapter
是 requests
与底层 HTTP 库(默认 urllib3
)的桥梁,负责:
-
连接池管理(复用 TCP 连接)
-
重试机制(通过
max_retries
参数) -
SSL 验证 和 代理支持
关键代码:
class HTTPAdapter(BaseAdapter): def __init__(self, max_retries=0, pool_connections=10, pool_maxsize=10): self.poolmanager = PoolManager( # urllib3 的连接池 num_pools=pool_connections, maxsize=pool_maxsize ) def send(self, request, **kwargs): # 1. 获取连接池 conn = self.get_connection(request.url) # 2. 发送请求(通过 urllib3) resp = conn.urlopen( method=request.method, url=request.url, body=request.body, headers=request.headers ) # 3. 构造 Response 对象 return self.build_response(request, resp)
3 models.py
(请求/响应模型)
定义 Request
和 Response
对象:
-
Request
:封装请求方法、URL、头、体等 -
Response
:封装状态码、头、Cookies、响应体等
关键代码:
class Request: def __init__(self, method=None, url=None, headers=None, data=None): self.method = method self.url = url self.headers = headers self.data = data class Response: def __init__(self): self.status_code = None self.headers = {} self.cookies = {} self.text = "" # 响应文本 self._content = None # 二进制响应体 def json(self): """解析 JSON 响应""" return json.loads(self.text)
4 api.py
(简化 API)
提供 get()
, post()
, put()
, delete()
等快捷方法,本质是调用 Session.request()
。
关键代码:
def get(url, params=None, **kwargs): return request("get", url, params=params, **kwargs) def request(method, url, **kwargs): with Session() as session: # 使用临时 Session return session.request(method=method, url=url, **kwargs)
设计模式
1 适配器模式(Adapter Pattern)
-
HTTPAdapter
是requests
和urllib3
之间的适配器。 -
允许未来替换底层 HTTP 实现(如换成
httplib2
)。
2 会话模式(Session Pattern)
-
Session
类封装了 连接池、Cookies、认证 等状态。 -
避免重复创建 TCP 连接,提升性能。
3 工厂模式(Factory Pattern)
-
Session.get_adapter()
根据 URL 的协议(http
/https
)返回对应的适配器。
关键实现细节
1 连接池管理
-
通过
urllib3.PoolManager
实现 TCP 连接复用。 -
默认每个主机保持 10 个连接(可配置)。
2 自动解码响应
-
根据响应头
Content-Type
自动选择解码方式(如utf-8
)。 -
源码位置:
response.py
中的iter_content()
方法。
3 重定向处理
-
默认最多 30 次重定向(防止循环)。
-
源码位置:
sessions.py
的resolve_redirects()
。
如何扩展 requests
1 自定义适配器
from requests.adapters import HTTPAdapter class MyAdapter(HTTPAdapter): def send(self, request, **kwargs): print("拦截请求:", request.url) return super().send(request, **kwargs) session = requests.Session() session.mount("https://", MyAdapter()) session.get("https://example.com") # 触发自定义适配器
2 修改默认行为
# 全局修改 User-Agent requests.utils.default_user_agent = lambda: "MyApp/1.0" # 禁用 SSL 验证(不推荐) requests.packages.urllib3.disable_warnings()
总结
模块 | 职责 | 关键类/函数 |
---|---|---|
sessions.py | 管理会话、Cookies、连接池 | Session , request() |
adapters.py | 连接底层 HTTP 库(如 urllib3) | HTTPAdapter |
models.py | 封装请求/响应数据结构 | Request , Response |
api.py | 提供简洁的 API(get/post) | get() , post() |
requests
的成功在于:
-
简洁的 API 设计(如
requests.get()
)。 -
强大的底层实现(基于
urllib3
的连接池和重试)。 -
良好的扩展性(适配器模式支持自定义 HTTP 层)。