今天在写爬虫的时候遇到一个错误,即:
requests.exceptions.SSLError: HTTPSConnectionPool(host=’httpbin.org’, port=443): Max retries exceeded with url: /get (Caused by SSLError(SSLEOFError(8, ‘EOF occurred in violation of protocol (_ssl.c:1129)’)))
如果你的requests请求代码加了verify=False参数,则错误应该是:
requests.exceptions.ProxyError: HTTPSConnectionPool(host=’httpbin.org’, port=443): Max retries exceeded with url: /get (Caused by ProxyError(‘Cannot connect to proxy.’, FileNotFoundError(2, ‘No such file or directory’)))
问题原因
触发这个错误是因为电脑开了代理(科学上网工具)的原因,如果关闭代理,则代码运行正常。
但是实际上代理是可以正常使用的,电脑网络也是正常的。
但是需求访问的资源偏偏是要使用代理的才能访问的。
最后我发现是urllib3的版本问题,使用urllib3==1.26或者是更高版本的就会这样。具体的原因就请你看:解决办法二。
解决办法一
降级urllib3,安装urllib3:1.25.11的版本可以解决。
使用命令:
pip install urllib3==1.25.11
安装好后发现则不会报错了。
解决办法一缺点
如果其他模块依赖urllib3==1.26+的版本,则可能遇见其他的错误提示。
PS:如果你没安装selenium或者是其他依赖更高版本的urllib3模块是不会有这个提示的。
我安装好后还有个问题,安装好urllib3 1.25.11的版本后,依然出现了错误提示,提示图片如下:
提示错误原因:
selenium 4.1.5 requires urllib3[secure,socks]~=1.26, but you have urllib3 1.25.11 which is incompatible.
elastic-transport 8.0.1 requires urllib3<2,>=1.26.2, but you have urllib3 1.25.11 which is incompatible.
# 大概意思就是 selenium 4.1.5 和 elastic-transport 8.0.1 分别对urllib3的版本要求是1.26、1.26.2
这样看来,如果我要再使用selenium、elastic-transport这两个东西的话,还得升级回去或者是使用虚拟环境(emmm…捂脸,至于其他的方法,除了使用虚拟环境外,我没找到…如果有大佬知道期待告诉我,现在,如果你想了解其他的解决方式,可以看这里了:解决办法二)。
不过不使用上述两个东西(selenium、elastic-transport)的小伙伴忽略就好了。
虚拟环境使用
再为了避免冲突的情况下,可以安装python虚拟环境,我们可以使用veny模块进行创建。
博主笔记:python虚拟环境使用
官方文档地址:https://docs.python.org/zh-cn/3/library/venv.html
venv 模块介绍:
venv 模块支持使用自己的站点目录创建轻量级“虚拟环境”,可选择与系统站点目录隔离。每个虚拟环境都有自己的 Python 二进制文件(与用于创建此环境的二进制文件的版本相匹配),并且可以在其站点目录中拥有自己独立的已安装 Python 软件包集。
具体的创建,我们看官方文档就好啦,这样在虚拟环境中完成另外一个项目,就不会有包冲突的情况了。
解决办法二
解决办法二,需要你自己去我下面列出的两篇文章中阅读查看,两篇文章中实际是有好几种方法的,看你自己需求去选择。
这篇文章发布于:2022-06-26 22:42:04这个时间,我当初是如何发现是urllib3的原因不记得了,不过今天(2024-07-09)在解决requests遇见的其他错误时候,发现了两篇优质文章更加详细的说明的原因和其他的一些解决方法,具体请你看↓
文章链接:Python 遭遇 ProxyError 问题记录 – DavyCloud – 博客园,【日常踩坑】从 SSLEOFError 到正确配置 Proxy-CSDN博客。
关于这篇文章中提到的(Caused by SSLError(SSLEOFError(8, ‘EOF occurred in violation of protocol (_ssl.c:1129)’)))错误或者是类似的错误(只要都是因为使用代理导致),可能可以再网上找到一些其他的解决办法,但是基本都没有说明原因,你在上面这两篇文章就可以知道原因了。
上述方法我的经验和踩坑
你看上面文章中解决方法之后,进行实操之前,建议你再看下我下面的经验,可以避免你重复踩坑:
如果你按照文章中提到的下面这种方式,将requests请求使用代理配置进行如下设置依然不行(我的配置后就是不行,依然报错,如果配置后成功了你是可以忽略的):
proxies={
'http': 'http://127.0.0.1:7890',
'https': 'http://127.0.0.1:7890' # https -> http
}
r = requests.get(url, proxies=proxies)
如果你配置后不行,那么去配置系统环境变量的方式是可以成功解决的(本人实测),配置完环境变量记得重启!
但是配置完环境变量后,我关闭代理,使用运行其他无需代理的爬虫,反而报本文章开头中的错误了,运行下面代码后,发现获取的是环境变量中配置的代理端口。
from urllib.request import getproxies
print(getproxies())
但是我们现在是不使用代理的状态,大部分人来说,使用代理,反而是少部分时候,这样更加不方便了。
我所使用的是Windows11 Python3.9,具体也不知道是啥原因,正常我没开启代理,应该不去获取才对…不过我没有时间纠结去深究了…
建议使用方式
所以,最后建议你使用【日常踩坑】从 SSLEOFError 到正确配置 Proxy-CSDN博客这篇文章中提到的修改Python urllib源代码的方式,我就是这样处理的,如果你有更好的方式,期待你评论留言,提前感谢。