Python requests.exceptions.SSLError:违反协议发生EOF
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33410577/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python requests.exceptions.SSLError: EOF occurred in violation of protocol
提问by mzilio
I would retrieve some information from an ABB G13 gateway that offer a RESTful JSON API. API is hosted by the gateway via https endpoint. Basic authentication mechanism is used for authentication. However all traffic goes through SSL layers.
我将从提供 RESTful JSON API 的 ABB G13 网关中检索一些信息。API 由网关通过 https 端点托管。使用基本认证机制进行认证。但是,所有流量都通过 SSL 层。
On linux with command:
在 linux 上使用命令:
curl -s -k -X GET -u user:password https://host/meters/a_serial/power
All goes well!
一切顺利!
I'm trying to write a script for windows in Python 2.7.10 with Requests 2.8.1 and with this code:
我正在尝试使用 Requests 2.8.1 和以下代码在 Python 2.7.10 中为 Windows 编写脚本:
import requests
requests.get('https://host/meters/a_serial/power', auth=('user', 'password'))
I have this error:
我有这个错误:
Traceback (most recent call last):
File "C:/Users/mzilio/PycharmProjects/pwrgtw/test.py", line 20, in <module>
requests.get('https://host/meters/a_serial/power', auth=('user', 'password'))
File "C:\Python27\lib\site-packages\requests\api.py", line 69, in get
return request('get', url, params=params, **kwargs)
File "C:\Python27\lib\site-packages\requests\api.py", line 50, in request
response = session.request(method=method, url=url, **kwargs)
File "C:\Python27\lib\site-packages\requests\sessions.py", line 468, in request
resp = self.send(prep, **send_kwargs)
File "C:\Python27\lib\site-packages\requests\sessions.py", line 576, in send
r = adapter.send(request, **kwargs)
File "C:\Python27\lib\site-packages\requests\adapters.py", line 433, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: EOF occurred in violation of protocol (_ssl.c:590)
I've searched for a solution and I've tried to fix with this code:
我已经搜索了一个解决方案,并尝试使用以下代码进行修复:
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.poolmanager import PoolManager
import ssl
class MyAdapter(HTTPAdapter):
def init_poolmanager(self, connections, maxsize, block=False):
self.poolmanager = PoolManager(num_pools=connections,
maxsize=maxsize,
block=block,
ssl_version=ssl.PROTOCOL_TLSv1)
s = requests.Session()
s.mount('https://', MyAdapter())
s.get('https://host/meters/a_serial/power')
But it doesn't work for me cause I get this error:
但这对我不起作用,因为我收到此错误:
Traceback (most recent call last):
File "C:/Users/mzilio/PycharmProjects/pwrgtw/test.py", line 16, in <module>
s.get('https://host/meters/a_serial/power')
File "C:\Python27\lib\site-packages\requests\sessions.py", line 480, in get
return self.request('GET', url, **kwargs)
File "C:\Python27\lib\site-packages\requests\sessions.py", line 468, in request
resp = self.send(prep, **send_kwargs)
File "C:\Python27\lib\site-packages\requests\sessions.py", line 576, in send
r = adapter.send(request, **kwargs)
File "C:\Python27\lib\site-packages\requests\adapters.py", line 433, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: EOF occurred in violation of protocol (_ssl.c:590)
I'm stuck on this problem. Could someone help me? Thanks!
我被这个问题困住了。有人可以帮助我吗?谢谢!
回答by hughdbrown
The only time I have seen errors of this nature have been times that I was using requests
to screen scrape data and I was using a multiprocessing library. I would either try your code without the pool manager or split your app into two apps, one that doles out urls and another that consumes them.
我唯一一次看到这种性质的错误是我requests
用来筛选抓取数据的时候,我使用的是多处理库。我要么在没有池管理器的情况下尝试您的代码,要么将您的应用程序拆分为两个应用程序,一个分发 url,另一个使用它们。
The client-server pair hereshould give you some ideas. I was able to scale my client out horizontally when I used the hacky server code to load all urls into a Queue in memory just before app.run
. Hope that helps.
客户端-服务器对这里应该给你一些想法。当我使用 hacky 服务器代码将所有 url 加载到内存中的队列之前时,我能够水平扩展我的客户端app.run
。希望有帮助。
回答by A G
I found it was going through a proxy when it should have connected to the server directly.
我发现它应该直接连接到服务器时通过代理。
I fixed this by doing
我通过这样做解决了这个问题
unset https_proxy
回答by James Lin
回答by varun
If you are getting this error for intermediate requests, you can refer to the solution mentioned in https://github.com/requests/requests/issues/3391.
如果中间请求出现此错误,您可以参考https://github.com/requests/requests/issues/3391 中提到的解决方案。
Basically, if you are making a lot of requests to a server and facing this issue with some of those requests you can use Session
to just retry the requests.
基本上,如果您向服务器发出大量请求,并且其中一些请求面临这个问题,您可以使用Session
重试请求。
Let me know if this works.
让我知道这个是否奏效。
回答by giving_the_world
This thing worked for me, just make sure whether these modules are installed or not, if not then install them, following are:
这东西对我有用,只需确保是否安装了这些模块,如果没有,则安装它们,以下是:
pip install ndg-httpsclient
pip install pyopenssl
pip install pyasn1
It removed my SSLError: EOF occurred in violation of protocol (_ssl.c:590) error.
它删除了我的 SSLError: EOF 发生违反协议 (_ssl.c:590) 错误。
Hope it helps.
希望能帮助到你。
回答by qff
Step 1: Check that Python supports TLS 1.1
步骤 1:检查 Python 是否支持 TLS 1.1
You may have a Python setup that only supports TLS 1.0 – not TLS 1.1 or above.
您的 Python 设置可能仅支持 TLS 1.0 – 不支持 TLS 1.1 或更高版本。
You can check it like this:
你可以这样检查:
Python 3
蟒蛇 3
> from urllib.request import urlopen
> urlopen('https://www.howsmyssl.com/a/check').read()
Python 2
蟒蛇 2
> from urllib2 import urlopen
> urlopen('https://www.howsmyssl.com/a/check').read()
Check the output for the key tls_version
. If it says TLS 1.0
and not TLS 1.1
or TLS 1.2
that could be the problem.
检查 key 的输出tls_version
。如果它说TLS 1.0
而不是,TLS 1.1
或者TLS 1.2
那可能是问题所在。
If you're using a virtualenv, be sure to run the command inside.
如果您使用的是 virtualenv,请确保在其中运行命令。
Step 2: Install Python with a newer version of OpenSSL
第 2 步:使用较新版本的 OpenSSL 安装 Python
In order support TLS 1.1 or above, you may need to install a newer version of OpenSSL, and the install Python again afterwards. This should give you a Python that supports TLS 1.1.
为了支持 TLS 1.1 或更高版本,您可能需要安装更新版本的 OpenSSL,然后再次安装 Python。这应该会给你一个支持 TLS 1.1 的 Python。
The process depends on your operating system – here's a guide for OS X.
该过程取决于您的操作系统 - 这是OS X指南。
virtualenv users
For me, the Python outside of my virtualenv had TLS 1.2 support, so just I removed my old virtualenv, and created a new one with the same packages and then it worked. Easy peasy!
virtualenv 用户
对我来说,virtualenv 之外的 Python 支持 TLS 1.2,所以我删除了旧的 virtualenv,并使用相同的包创建了一个新的,然后它就可以工作了。十分简单!