【日常踩坑】从 SSLEOFError 到正确配置 Proxy
本文主要参考 Python 遭遇 ProxyError 问题记录 重新梳理改写
踩坑
在前几天搞定 pip
的 SSL 认证之后,结果在利用 requests
库请求 HTTPS 网站又出现了 SSLError(SSLEOFError(8, 'EOF occurred in violation of protocol (_ssl.c:1129)'))
的 SSL 相关错误
经过一系列的查询资料和测试发现,原因竟然在于 python
自身的 urllib
库没有正确配置 HTTPS 代理
代理服务器
普通的代理服务器
上面提及的 HTTP(S) 代理,其实是通过代理服务器进行 HTTP(S) 流量的转发的意思,也是在上图中的 黄线 所代表的协议,文中后续用 出口协议 来指代
而和代理服务器之间其实也需要一种协议进行通信,就是在上图中的 绿线 部分,文中后续用 入口协议 来指代
而 入口协议 通常使用较多的都是 HTTP 和 Socks4/Socks5,很少有采用 HTTPS 作为与代理服务器间的连接协议,这点也是导致之前报错的主要原因
因国家法律规定,部分内容已删除,完整内容请查看文章末尾链接
代理配置
因此 入口协议 和 出口协议 之间其实没有任何因果联系,以 CFW 为例
它的 入口协议 支持 http 以及 socks,而且都在同一个端口,因此正确的代理配置应该是这样的:
# 正确的配置方式
HTTP_PROXY=http://127.0.0.1:7890
HTTPS_PROXY=http://127.0.0.1:7890
或者
# 正确的配置方式
HTTP_PROXY=socks5://127.0.0.1:7890
HTTPS_PROXY=socks5://127.0.0.1:7890
重点:
HTTPS_PROXY
也应该填写 http://127.0.0.1:7890
,因为 HTTPS_PROXY
中 HTTPS
代表的是 出口协议,而 http://127.0.0.1:7890
代表和 127.0.0.1:7890
服务器之间的 入口协议 是 HTTP
追根溯源
# 错误的配置方式
HTTP_PROXY=http://127.0.0.1:7890
HTTPS_PROXY=https://127.0.0.1:7890
而之前一直采用的上述错误配置,则会因为旧版本的 python
的 pip
内含的 urllib3
不支持 HTTPS 的 入口协议 ,自动转换成了 HTTP 的 入口协议 进行连接了
urllib3
但是在 urllib3
库升级到 v1.26.0 版本之后,增加了对 HTTPS 的 入口协议 的支持,参见 Add support for HTTPS connections to proxies.
pip
pip
内置了的 requests
和 urllib3
包,而不依赖全局的 requests
和 urllib3
包
当 pip
版本高于 20.3 时,内置的 requests
包升级到了 v2.25.0,urllib3
包也升级到了 v1.26.2,也就是说开始支持 HTTPS 的 入口协议 了,参见 pypa/pip 20.3 (2020-11-30) NEWS.rst
万恶之源 urllib
但是其实他们都不是罪魁祸首,真正的原因其实在 python 的内置包 urllib
上
CFW
等软件一般会通过修改 Windows 注册表的 计算机\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings
目录下的 ProxyServer
来配置代理服务器地址端口以及 ProxyEnable
是否启用代理
CFW
在配置代理服务器时,仅仅给出了地址和端口,并没有给出 入口协议
# urllib 配置代理的源码摘录:
if '=' in proxyServer:
# Per-protocol settings
for p in proxyServer.split(';'):
protocol, address = p.split('=', 1)
# See if address has a type:// prefix
if not re.match('(?:[^/:]+)://', address):
address = '%s://%s' % (protocol, address)
proxies[protocol] = address
else:
# Use one setting for all protocols
if proxyServer[:5] == 'http:':
proxies['http'] = proxyServer
else:
proxies['http'] = 'http://%s' % proxyServer
proxies['https'] = 'https://%s' % proxyServer
proxies['ftp'] = 'ftp://%s' % proxyServer
按照上面给出的 urllib
库源码逻辑,会将代理配置为
proxies = {
'http': 'http://127.0.0.1:7890',
'https': 'https://127.0.0.1:7890',
'ftp': 'ftp://127.0.0.1:7890'
}
因此导致了 pip
、requests
等上层包,访问 HTTPS 网站时会错误的使用 https://127.0.0.1:7890
代理,而 CFW
根本不支持 HTTPS 的 入口协议,所以才会产生这么一系列的错误
个人推荐可以根据自己常用的工具所支持的 入口协议 来修改 urllib
库源码逻辑(文件位置一般在 ***/python3.*/urllib/request.py
或者 ***/anaconda3/Lib/urllib/request.py
)
if '=' in proxyServer:
# Per-protocol settings
for p in proxyServer.split(';'):
protocol, address = p.split('=', 1)
# See if address has a type:// prefix
if not re.match('(?:[^/:]+)://', address):
address = '%s://%s' % (protocol, address)
proxies[protocol] = address
else:
# Use one setting for all protocols
proxies['http'] = 'http://%s' % proxyServer
proxies['https'] = 'http://%s' % proxyServer
proxies['ftp'] = 'http://%s' % proxyServer
或者简单的按照下面的方式进行修改(并不一定适用所有情况)
if '=' in proxyServer:
# Per-protocol settings
for p in proxyServer.split(';'):
protocol, address = p.split('=', 1)
# See if address has a type:// prefix
if not re.match('(?:[^/:]+)://', address):
address = '%s://%s' % (protocol, address)
proxies[protocol] = address
else:
# Use one setting for all protocols
proxies['http'] = proxyServer
proxies['https'] = proxyServer
proxies['ftp'] = proxyServer
参考资料
- 【博客园】Python 遭遇 ProxyError 问题记录
- 【维基百科】代理服务器
- 【GitHub】pypa/pip Pip 20.3+ break proxy connection
- 【GitHub】urllib3/urllib3 Add support for HTTPS connections to proxies.
- 【GitHub】pypa/pip 20.3 (2020-11-30) NEWS.rst
本文作者: ywang_wnlo
本文链接: https://ywang-wnlo.github.io/posts/76f6af57.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
【日常踩坑】从 SSLEOFError 到正确配置 Proxy的更多相关文章
- 踩坑系列:MySql only_full_group_by配置,竟导致所有应用报错?
1. 踩坑经历 一个很平常的下午,大家都在埋头认真写bug呢,突然企业微信群里炸锅了,好多应用都出现大量的Error日志,而且都报同一个错误,就是下面这个: Caused by: com.mysql. ...
- 日常踩坑 — 相邻元素之间的margin合并问题。
踩坑:使用v-for渲染的组件,当然图中的id已经换成class,还是没有解决这个问题,于是各种查找资料,我就不信简单的CSS问题这么难解决! v-for渲染组件级传值: <div class= ...
- 日常踩坑-------新手使用idea
mybatis在idea的maven项目中的坑 今天遇到mybatis的报错,搞了好久才搞懂,在网上找了好久的相似案例,也没有搞定,先来看下网上常见的解决办法吧,相信也能解决大部分人的报错. 1.ma ...
- 日常踩坑 searter
目录 es7中的async, await Django生成二维码并转为base64 Django配置404页面 很傻逼的坑 no module named pil 其他 es7中的async, awa ...
- Spring Cloud之踩坑01 -- Eureka高可用配置
转载:https://blog.csdn.net/dear_Alice_moon/article/details/79373955 问题描述: 在进行Eureka高可用配置时,控制台一直出现“.... ...
- 日常踩坑——Dev C++ pow()函数的坑
坑 Dev C++ pow()函数 那年冬天,显示屏前坐着如喽啰,那时候我含泪发誓,再也不用Dev. 蓝桥杯官网给提供的版本,没办法bug也得硬着头皮用. 16年蓝桥杯的第八题 四平方和定理: 在De ...
- 日常踩坑笔记:spring的context:property-placeholder标签
背景: 原来的项目一直跑着没有问题,今天突然想在原有项目的基础上,加上redis进行数据的缓存,原来项目的架构就是传统的SSM框架,于是,大刀阔斧的开始改装了... 编写redis的配置文件——red ...
- 日常踩坑——rand()总是出现重复数据
写了一个生成随机数组的函数,然后跑出来,结果总是…… 然后,很奇怪的是一步一步调试,它就没问题了,WTF??? 问题出在:重复写了srand(time(NULL)),只保留一个就好了. int* ge ...
- 【React Native】日常踩坑记录_以后将持续更新
作为一名有理想.有抱负的一代iOS程序员,本着“我头发够多,还能学”的原则,我选择了追随那些大佬的脚步,于2018年开始了React Native. 第一步:找文档.准备安装开发环境: 第二步:一步步 ...
- 使用IDEA配置Maven + SpringMVC + Mybatis 【一步一步踩坑详细配置完成】
PS:初学,想使用Maven配置一个SpringMVC的开发环境,照着网上的各种图文解说,配置了好久都没成功,有些写的不够详细,有些只有写一半,走了不少弯弯绕绕,踩了不少的坑,此文将正确配置成功的步骤 ...
随机推荐
- django4 前后端分离和不分离的优缺点
Django4可以采用前后端分离或者不分离两种方式来开发Web应用,它们各有优缺点. 前后端分离的优点: 前后端职责分离:前端负责视图展示.用户交互,后端负责数据处理.逻辑处理,分工明确,开发效率高. ...
- 合合信息亮相CCIG2023:多位大咖共话智能文档未来,文档图像内容安全还面临哪些技术难题?
近日,中国图象图形大会(CCIG 2023)(简称"大会")在苏州圆满落幕.本届大会以"图象图形·向未来"为主题,由中国科学技术协会指导,中国图象图形学学会 ...
- DP杂谈【持续更新中】
什么是DP? 推荐看一下. 正文 滚动数组优化 在一些空间贼小,时间还好的 DP 题目里,会用到优化空间的小技♂巧--滚动数组优化. 滚动数组,顾名思义,一个会滚动的数组,主要是怎样个滚法呢?接下来我 ...
- vue平铺日历组件之按住ctrl、shift键实现跨月、跨年多选日期的功能
已经好久没有更新过博客了,大概有两三年了吧,因为换了工作,工作也比较忙,所以也就没有时间来写技术博客,期间也一直想写,但自己又比较懒,就给耽误了.今天这篇先续上,下一篇什么时候写,我也不知道,随心所欲 ...
- flutter填坑之旅(环境搭建篇)
自从Google 在 2018 世界移动大会上发布 Flutter 的 Beta 版本,看看官方的介绍Flutter widgets are built using a modern framewor ...
- 2023-06-03:redis中pipeline有什么好处,为什么要用 pipeline?
2023-06-03:redis中pipeline有什么好处,为什么要用 pipeline? 答案2023-06-03: Redis客户端执行一条命令通常包括以下四个阶段: 1.发送命令:客户端将要执 ...
- CtfShow信息收集1-20攻略
CtfShow信息收集1-20关攻略 简单更新一下CTF关于信息收集的题目,总共20道,网站地址:https://ctf.show/challenges 第一关 我们可以看到提示:开发注释没有及时删除 ...
- 【Azure 应用服务】App Service for Container 无法拉取Docker Hub中的镜像替代方案
问题描述 创建App Service Container服务,选择从Docker Hub中获取appsmith/appsmith-ce 镜像(https://www.appsmith.com/ &am ...
- 2023-06-20:给定一个长度为N的数组arr,arr[i]表示宝石的价值 你在某天遇到X价值的宝石, X价值如果是所有剩余宝石价值中的最小值,你会将该宝石送人 X价值如果不是所有剩余宝石价值中的
2023-06-20:给定一个长度为N的数组arr,arr[i]表示宝石的价值 你在某天遇到X价值的宝石, X价值如果是所有剩余宝石价值中的最小值,你会将该宝石送人 X价值如果不是所有剩余宝石价值中的 ...
- 构建 JavaScript ChatGPT 插件
聊天插件系统是一种令人兴奋的新方式,可以扩展ChatGPT的功能,纳入您自己的业务数据,并为客户与您的业务互动增加另一个渠道.在这篇文章中,我将解释什么是聊天插件,它们能做什么,以及你如何用JavaS ...