1. 问题背景
在使用Python的requests库进行HTTP请求时,session.raw方法因其底层原始响应处理能力备受开发者青睐。然而,当涉及HTTPS请求时,SSL证书验证问题成为高频痛点。典型错误包括:
SSLError: [SSL: CERTIFICATE_VERIFY_FAILED]requests.exceptions.SSLError异常- 自签名证书或过期证书导致的连接中断
2. 根本原因分析
SSL/TLS证书验证是HTTPS安全通信的核心环节。以下场景会触发验证失败:
- 证书链不完整:服务器未返回完整的中间证书
- 域名不匹配:证书Subject Alternative Name (SAN)与请求域名不符
- 系统CA存储缺失:Python无法定位系统的根证书库
# 示例错误代码
import requests
s = requests.Session()
resp = s.get('https://expired.badssl.com', verify=True) # 显式触发验证
3. 解决方案
3.1 临时禁用验证(仅限测试环境)
通过设置verify=False跳过验证,但会引发安全警告:
resp = s.get('https://example.com', verify=False)
# 需配合禁用警告
import urllib3
urllib3.disable_warnings()
3.2 指定自定义CA证书
使用verify参数指定PEM格式的证书文件:
resp = s.get('https://example.com', verify='/path/to/cert.pem')
3.3 修改Session默认配置
全局配置Session对象的验证策略:
s = requests.Session()
s.verify = '/path/to/cert_bundle.crt' # 或 False
4. 高级技巧
4.1 动态证书加载
结合certifi库扩展CA存储:
import certifi
s.verify = certifi.where() # 使用certifi的证书库
4.2 自定义验证逻辑
继承requests.adapters.HTTPAdapter实现自定义验证:
class CustomAdapter(requests.adapters.HTTPAdapter):
def cert_verify(self, conn, url, verify, cert):
super().cert_verify(conn, url, '/custom/path', cert)
s.mount('https://', CustomAdapter())
5. 生产环境最佳实践
- 使用Let's Encrypt等免费CA签发有效证书
- 定期检查证书有效期(推荐工具:
openssl x509 -checkend) - 在Docker中确保
ca-certificates包已更新