如何用Python Requests按域名(通配子域名)挂载自定义适配器?
问题需求
需要为example.org下所有子域名(包括动态生成的、重定向跳转的)自动应用自定义CA证书链,无需每次调用get/post时手动指定verify参数,同时让该设置贯穿整个请求流程(包括重定向环节)。
解决方案
方案1:重写Session的send方法(最彻底,覆盖所有请求)
通过自定义Session类,重写核心的send方法,在每次请求(包括重定向自动发起的请求)前检查域名是否属于目标主域,自动注入CA证书路径:
from requests import Session from urllib.parse import urlparse class DomainCAVerifySession(Session): def __init__(self, domain_ca_map=None, *args, **kwargs): super().__init__(*args, **kwargs) # 存储「主域名-CA证书路径」的映射,支持多域名配置 self.domain_ca_map = domain_ca_map or {} def send(self, request, **kwargs): # 解析请求域名,剥离端口号 parsed_url = urlparse(request.url) domain = parsed_url.netloc.split(':')[0] # 匹配目标主域(含所有子域名) for target_domain, ca_path in self.domain_ca_map.items(): if domain == target_domain or domain.endswith(f'.{target_domain}'): # 自动设置verify参数,用户手动传入的参数优先级更高 kwargs.setdefault('verify', ca_path) break # 调用原生send方法处理请求 return super().send(request, **kwargs) # 使用示例 s = DomainCAVerifySession( domain_ca_map={"example.org": "/path/to/ca/chain"} ) # 直接发起请求,无需手动指定verify response = s.get("https://download.example.org/file") # 重定向到动态子域名(如p06636710s64948.example.org)时,会自动应用CA证书
方案2:自定义HTTPAdapter(轻量化适配)
如果不想修改Session核心逻辑,可以自定义Adapter,挂载后动态检查域名并设置verify:
from requests import Session from requests.adapters import HTTPAdapter from urllib.parse import urlparse class DomainCAAdapter(HTTPAdapter): def __init__(self, target_domain, ca_path, *args, **kwargs): super().__init__(*args, **kwargs) self.target_domain = target_domain self.ca_path = ca_path def send(self, request, **kwargs): parsed_url = urlparse(request.url) domain = parsed_url.netloc.split(':')[0] # 匹配目标主域及子域名 if domain == self.target_domain or domain.endswith(f'.{self.target_domain}'): kwargs.setdefault('verify', self.ca_path) return super().send(request, **kwargs) # 使用示例 s = Session() # 为HTTP和HTTPS请求都挂载适配器 s.mount("http://", DomainCAAdapter("example.org", "/path/to/ca/chain")) s.mount("https://", DomainCAAdapter("example.org", "/path/to/ca/chain")) # 发起请求无需手动指定verify s.get("https://download.example.org/file")
关于functools.partial方案的说明
用partial包装get/post等方法只能覆盖顶层手动发起的请求,无法处理重定向过程中requests自动发起的后续请求,因此重写send方法是更可靠的选择——所有请求(包括重定向)最终都会经过send方法处理。
内容的提问来源于stack exchange,提问作者kratsg
相关产品推荐
相关产品推荐

