1. 项目概述
作为一名长期使用Python进行网络爬虫开发的工程师,我深知requests库在实际项目中遇到的各种网络问题有多令人头疼。特别是在企业级爬虫系统中,超时、SSL证书错误和代理失效这三大问题几乎每天都会遇到,轻则导致数据采集中断,重则触发目标网站的反爬机制。
最近我接手的一个电商价格监控项目,就因为这些网络问题导致凌晨的定时任务频繁失败。经过两周的集中攻关和线上实测,终于总结出一套稳定的解决方案。这套方案已经在我们日均请求量200万+的生产环境中稳定运行了3个月,成功率保持在99.8%以上。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心问题解析
2.1 超时问题全解
requests的超时分为连接超时(connect timeout)和读取超时(read timeout)两种。很多开发者只设置一个总超时,这是不专业的做法。正确的超时配置应该是:
python复制TIMEOUT = (3.05, 27) # (连接超时, 读取超时)
为什么是这两个神奇数字?
- 3.05秒:TCP三次握手最长等待时间(3秒)加上少量冗余
- 27秒:基于HTTP/1.1的keep-alive默认超时时间30秒,预留3秒缓冲
实测中发现,对于不同场景需要动态调整:
- 内网API:可缩短为(1, 5)
- 海外网站:建议(10, 30)
- 文件下载:读取超时应按文件大小调整
重要提示:超时设置过短会导致高频重试,可能触发429 Too Many Requests错误
2.2 SSL证书问题深度处理
SSL错误通常表现为:
code复制requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED]
常规解决方案是直接关闭验证:
python复制requests.get(url, verify=False) # 危险!
但这样会降低安全性。更专业的做法是:
- 导出目标网站证书链:
bash复制openssl s_client -showcerts -connect example.com:443 </dev/null 2>/dev/null | openssl x509 -outform PEM > cert.pem
- 在代码中指定证书路径:
python复制CERT_PATH = '/path/to/cert.pem'
requests.get(url, verify=CERT_PATH)
对于自签名证书,还需要处理证书链问题。我开发了一个自动修复证书链的工具函数:
python复制def fix_ssl_cert(url):
from OpenSSL import SSL
import certifi
# 获取服务器证书链
cert_chain = SSL.Context(SSL.SSLv23_METHOD).get_cert_chain(url)
# 合并系统CA证书和服务器证书
with open(certifi.where(), 'rb') as f:
ca_certs = f.read()
merged_certs = ca_certs + b'\n'.join(cert_chain)
