Python requests.exceptions.SSLError:EOF违反协议

时间:2015-10-29 09:38:33

标签: python ssl https python-requests

我会从提供RESTful JSON API的ABB G13网关中检索一些信息。 API由网关通过https端点托管。 基本认证机制用于认证。然而所有的交通 通过SSL层。

在Linux上使用命令:

curl -s -k -X GET -u user:password https://host/meters/a_serial/power

一切顺利!

我试图在Python 2.7.10中使用Requests 2.8.1并使用以下代码编写Windows脚本:

import requests
requests.get('https://host/meters/a_serial/power', auth=('user', 'password'))

我有这个错误:

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)

我已经搜索了解决方案,并且我已经尝试使用此代码修复:

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')

但它并不适合我,因为我收到了这个错误:

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)

我坚持这个问题。有人能帮助我吗?谢谢!

6 个答案:

答案 0 :(得分:8)

这件事对我有用,只是确定是否安装了这些模块,如果没有安装它们,以下是:

pip install ndg-httpsclient

pip install pyopenssl

pip install pyasn1

它删除了我的SSLError:EOF发生违反协议(_ssl.c:590)错误。

希望它有所帮助。

答案 1 :(得分:3)

我有完全相同的错误,结果是我没有安装ndg-httpsclients,请参阅我在github中提出的原始issue

答案 2 :(得分:2)

我发现它应该通过代理直接连接到服务器。

我通过

修复了这个问题
unset https_proxy

答案 3 :(得分:1)

如果您收到中间请求的此错误,可以参考https://github.com/requests/requests/issues/3391中提到的解决方案。

基本上,如果您向服务器发出大量请求并遇到其中一些请求的问题,则可以使用Session重试请求。

让我知道这是否有效。

答案 4 :(得分:1)

步骤1:检查Python是否支持TLS 1.1

您可能拥有仅支持TLS 1.0的Python设置 - 而不是TLS 1.1或更高版本。

您可以这样检查:

Python 3

> from urllib.request import urlopen
> urlopen('https://www.howsmyssl.com/a/check').read()

Python 2

> from urllib2 import urlopen
> urlopen('https://www.howsmyssl.com/a/check').read()

检查键tls_version的输出。如果它显示TLS 1.0而不是TLS 1.1TLS 1.2可能是问题。

如果你正在使用virtualenv,请务必在里面运行命令。

步骤2:使用较新版本的OpenSSL

安装Python

为了支持TLS 1.1或更高版本,您可能需要安装较新版本的OpenSSL,然后再安装Python。这应该会给你一个支持TLS 1.1的Python。

此过程取决于您的操作系统 - 这是OS X的指南。

virtualenv用户
对我来说,我的virtualenv之外的Python有TLS 1.2支持,所以我删除了我的旧virtualenv,并创建了一个具有相同包的新的,然后它工作。容易腻!

答案 5 :(得分:0)

我唯一一次看到这种性质的错误是因为我使用requests来筛选数据并且我正在使用多处理库。我会在没有池管理器的情况下尝试您的代码,或者将您的应用程序拆分为两个应用程序,一个用于发布URL,另一个用于使用它们。

客户端 - 服务器对here应该给你一些想法。当我使用hacky服务器代码在app.run之前将所有URL加载到内存中的Queue时,我能够横向扩展我的客户端。希望有所帮助。