Python 2.7.10使用requests调用GitLab API失败,curl/Postman正常求助
这种情况确实挺让人挠头的——明明curl和Postman都能顺利拿到响应,偏偏用requests就抛出连接重置的错误,还是在已经设置了verify=False的情况下。结合Python 2.7.10这个比较老旧的版本,我整理了几个大概率能解决问题的方向:
1. 升级requests及依赖库,补全TLS支持
Python 2.7.10自带的ssl模块默认对TLS 1.2及以上版本的支持有限,而现代GitLab服务器通常会禁用老旧的TLS协议(比如TLS 1.0/1.1)。curl和Postman默认支持的TLS版本更齐全,所以能正常请求,而旧版本的requests可能因为协议不匹配被服务器主动断开连接。
解决方法:
- 安装兼容Python 2.7的最新版requests(最后一个支持Python 2.7的版本是2.27.1),同时升级依赖的urllib3:
pip install --upgrade requests==2.27.1 urllib3==1.26.15 - 如果升级后还是不行,可以手动指定使用TLS 1.2协议:
注:Python 2.7.9及以上版本才支持import requests import ssl # 创建TLS 1.2的SSL上下文 tls_ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) response = requests.get( 'https://gitlab.example.com/api/v4/projects', verify=False, ssl_context=tls_ctx ) print(response.json())PROTOCOL_TLSv1_2,你的2.7.10满足要求。
2. 模拟标准User-Agent请求
有些服务器会拒绝带有python-requests/xxx标识的User-Agent,而curl和Postman用的是更通用的请求头。可以尝试把User-Agent改成curl或者浏览器的样式:
import requests headers = { 'User-Agent': 'curl/7.68.0' # 换成你本地curl的版本,或者用浏览器UA } response = requests.get( 'https://gitlab.example.com/api/v4/projects', verify=False, headers=headers )
3. 禁用连接复用或代理
Python 2.7版本的requests在连接池复用逻辑上可能存在bug,导致连接被重置。可以尝试关闭连接复用:
import requests headers = { 'Connection': 'close' } response = requests.get( 'https://gitlab.example.com/api/v4/projects', verify=False, headers=headers )
另外,检查是否有系统代理被requests自动读取(curl可能没用到这些代理),可以手动禁用代理:
import requests response = requests.get( 'https://gitlab.example.com/api/v4/projects', verify=False, proxies={"http": None, "https": None} )
4. 检查系统层面的SSL证书缓存(小众情况)
虽然你设置了verify=False,但Python 2.7的requests可能还是会读取系统层面的证书缓存。可以尝试清除本地的SSL证书缓存,或者指定一个空的证书文件路径(不过这个操作要谨慎):
import requests response = requests.get( 'https://gitlab.example.com/api/v4/projects', verify='/dev/null' # Linux/macOS下,Windows可以用空文件路径 )
优先从升级requests+指定TLS版本这个方向排查,这是Python 2.7环境下最常见的原因。如果还是不行,可以逐一尝试上面的其他方案。
内容的提问来源于stack exchange,提问作者emmdee

