Python 遭遇 ProxyError 问题记录

最近遇到的一个问题,在搞清楚之后才发现这么多年的 HTTPS_PROXY 都配置错了!

起因

想用 Python 在网上下载一些图片素材,结果 requests 报错 requests.exceptions.ProxyError,
具体的错误信息见下面。当然第一时间是把系统代理关了,结果访问就正常了。

如果只是这样,可能我就觉得是代理有问题,然后关了用就行了,但是偏偏想要下载的资源里是必须要走代理的,所以只能想办法解决。

下面先介绍一下具体的情况:

解决过程

操作系统:Windows 10

Python: 3.8(有虚拟环境)

requests 通过代理访问外网时报错如下:

Traceback (most recent call last): File "E:\code\Python\.venv\smalltools\lib\site-packages\urllib3\connectionpool.py", line 696, in urlopen self._prepare_proxy(conn) File "E:\code\Python\.venv\smalltools\lib\site-packages\urllib3\connectionpool.py", line 964, in _prepare_proxy conn.connect() File "E:\code\Python\.venv\smalltools\lib\site-packages\urllib3\connection.py", line 359, in connect conn = self._connect_tls_proxy(hostname, conn) File "E:\code\Python\.venv\smalltools\lib\site-packages\urllib3\connection.py", line 496, in _connect_tls_proxy return ssl_wrap_socket( File "E:\code\Python\.venv\smalltools\lib\site-packages\urllib3\util\ssl_.py", line 432, in ssl_wrap_socket ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls) File "E:\code\Python\.venv\smalltools\lib\site-packages\urllib3\util\ssl_.py", line 474, in _ssl_wrap_socket_impl return ssl_context.wrap_socket(sock) File "C:\Users\Davy\AppData\Local\Programs\Python\Python38\lib\ssl.py", line 500, in wrap_socket return self.sslsocket_class._create( File "C:\Users\Davy\AppData\Local\Programs\Python\Python38\lib\ssl.py", line 1041, in _create self.do_handshake() File "C:\Users\Davy\AppData\Local\Programs\Python\Python38\lib\ssl.py", line 1310, in do_handshake self._sslobj.do_handshake() OSError: [Errno 0] Error

因为浏览器访问是没有问题的,代理本身应该没有问题。

按照这个错误信息在网上搜了一下,比较接近的帖子给的解决方案有安装 ssl 模块之类,都照着检查了一遍,问题还是没有解决。

因为网上的内容有些年头了,并且我觉得使用代理是非常常见的场景,既然没多少人报这个问题,那么很可能只是偶然的 bug,于是想着把版本再升级试试。

升级到 python 3.9 ,错误仍然存在,提示略有变化:

Traceback (most recent call last): File "C:\Users\Davy\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\connectionpool.py", line 696, in urlopen self._prepare_proxy(conn) File "C:\Users\Davy\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\connectionpool.py", line 964, in _prepare_proxy conn.connect() File "C:\Users\Davy\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\connection.py", line 359, in connect conn = self._connect_tls_proxy(hostname, conn) File "C:\Users\Davy\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\connection.py", line 496, in _connect_tls_proxy return ssl_wrap_socket( File "C:\Users\Davy\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\util\ssl_.py", line 432, in ssl_wrap_socket ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls) File "C:\Users\Davy\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\util\ssl_.py", line 474, in _ssl_wrap_socket_impl return ssl_context.wrap_socket(sock) File "C:\Users\Davy\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 500, in wrap_socket return self.sslsocket_class._create( File "C:\Users\Davy\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 1040, in _create self.do_handshake() File "C:\Users\Davy\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 1309, in do_handshake self._sslobj.do_handshake() ssl.SSLEOFError: EOF occurred in violation of protocol (_ssl.c:1122)

好歹错误信息有点变化,于是按照最下面 ssl.SSLEOFError: EOF occurred in violation of protocol (_ssl.c:1122) 去谷歌,并没有找到解决办法,但是发现有人在不久前遇到了相同的问题,并且通过降级 Python 3.7 解决了。

参见:https://v2ex.com/t/738031

先重新安装 Python 3.7 试了一下果然可行,并且意外地发现在 Python 3.8 环境下也是可行的,也就是可以排除 Python 版本的问题,那么自然就怀疑是某个包引发的。

通过简单地对比和排除,很快就发现了问题所在:

模块 urllib3 的版本,报错的是 1.26.3,没报错的是 1.25.11

在原报错环境中使用下面命令重装低版本 urllib3:

pip install urllib3==1.25.11

然后测试果然就没问题了。

问题根源

先查了一下 urllib3 的更新日志,应该是 1.26.0 的修改导致的:

image-20210205233412643

按照这个更新日志,明明应该是增加了 HTTPS 的支持,怎么反而让它失效了呢?

我一时搞不明白这个问题,但是想起了我最近遭遇到了另一个问题,然后意外地找到了真相:

同样遭遇代理错误的 pip

同样是在这个环境中,其实在一开始我就遭遇了 pip install 安装包失败的问题,报错信息是:

​ 'ProxyError('Cannot connect to proxy.', FileNotFoundError(2, 'No such file or directory'))'

同样是取消系统代理就能正常安装,就没太在意了。

但是在降级 urllib3 解决了 requests 的 ProxyError 之后,我开始怀疑 pip 安装是不是也是这个问题呢?

直接在降级了 urllib3 的环境中测试了一下,错误仍然存在,但是版本整体较低的环境中,是没有问题的!

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwdzxx.html