记录 python request ProxyError报错
【出自】:https://zhuanlan.zhihu.com/p/350015032 侵删
解决办法:在原报错环境中使用下面命令重装低版本 urllib3
:
pip install urllib3==1.25.11
问题根源
先查了一下 urllib3
的更新日志,应该是 1.26.0
的修改导致的:
按照这个更新日志,明明应该是增加了 HTTPS
的支持,怎么反而让它失效了呢?
我一时搞不明白这个问题,但是想起了我最近遭遇到了另一个问题,然后意外地找到了真相:
同样遭遇代理错误的 pip
同样是在这个环境中,其实在一开始我就遭遇了 pip install
安装包失败的问题,报错信息是:
'ProxyError('Cannot connect to proxy.', FileNotFoundError(2, 'No such file or directory'))'
同样是取消系统代理就能正常安装,就没太在意了。
但是在降级 urllib3
解决了 requests
的 ProxyError
之后,我开始怀疑 pip
安装是不是也是这个问题呢?
直接在降级了 urllib3
的环境中测试了一下,错误仍然存在,但是版本整体较低的环境中,是没有问题的!
于是继续对比版本包,结果在 pip
包的路径下发现有一个 _vendor\urllib3
目录,原来 pip
是直接把 urllib3
集成到了自己的包里面,不受系统安装包的影响。检查其中的 _version.py
里的版本信息,果然也是 1.26.x
。
出错的 pip
的版本是 20.3
,把 pip
也降级到 20.2
以下,就没有问题了。
显然,鉴于 pip
的高频使用,这种致命的问题不可能没人报,所以在 pip
项目的 issue
列表里很快就找到了相关讨论:
urllib3
更新了啥
根据 https://github.com/pypa/pip/issues/9216#issuecomment-741836058 所说,更改代理配置可以解决问题:
绕了好大一圈大概明白是怎么回事了:
以前 urllib3
其实并不支持 https
代理,也就是说代理服务器的地址虽然大家配置的是 https
,但是一直都是悄无声息地就按照 http
连接的,刚好代理服务器确实也只支持 http
,所以皆大欢喜。
现在 urllib3
要支持 https
代理了,那么既然配置代理是 https
就尝试用 https
的方式去连接,但是由于代理服务器其实只支持 http
,所以没法处理请求,ssl
握手阶段就出错了。
注意,这里的 https
是指代理服务器自己的,和我们要访问的目标网站无关。
因为目标网站的协议和代理服务器的协议并不要求一样,所以只需要更改代理配置 ,将访问 https
网站的代理服务器地址改为 http
即可,也就是这样:
HTTPS_PROXY=http://proxy_ip:proxy_port
前面的 HTTPS_
表示,如果访问的站点是 https
的,需要走这里配置的代理服务器;后面的 http://
则表示这个代理服务器自己只支持 http
。
而我们一直以来看到的配置建议,这两者前后通常都是保持一致的:
HTTP_PROXY=http://proxy_ip:proxy_port
HTTPS_PROXY=https://proxy_ip:proxy_port
这个是错误的!