You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 16:06:27