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

mzi*_*lio 9 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
Run Code Online (Sandbox Code Playgroud)

一切顺利!

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

import requests
requests.get('https://host/meters/a_serial/power', auth=('user', 'password'))
Run Code Online (Sandbox Code Playgroud)

我有这个错误:

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)
Run Code Online (Sandbox Code Playgroud)

我已经搜索了一个解决方案,我试图修复此代码:

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')
Run Code Online (Sandbox Code Playgroud)

但它不适合我,因为我得到这个错误:

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)
Run Code Online (Sandbox Code Playgroud)

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

qff*_*qff 17

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

\n

您的 Python 设置可能仅支持 TLS 1.0 \xe2\x80\x93,而不支持 TLS 1.1 或更高版本。

\n

你可以这样检查:

\n

蟒蛇3

\n
from urllib.request import urlopen\nurlopen(\'https://www.howsmyssl.com/a/check\').read()\n
Run Code Online (Sandbox Code Playgroud)\n

蟒蛇2

\n
from urllib2 import urlopen\nurlopen(\'https://www.howsmyssl.com/a/check\').read()\n
Run Code Online (Sandbox Code Playgroud)\n

(如果您发现,urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:852)>您可能必须禁用证书验证。注意:这样做将禁用 SSL 保护,防止冒充或拦截该网站流量的作恶者 - 请参阅https://en.wikipedia.org/wiki/Man-in-the -middle_attack\n)

\n
import ssl\nurlopen(\'https://www.howsmyssl.com/a/check\', context=ssl._create_unverified_context()).read()\n
Run Code Online (Sandbox Code Playgroud)\n

检查 key 的输出tls_version。如果它说TLS 1.0而不是TLS 1.1或者TLS 1.2那可能就是问题所在。

\n

如果您使用的是 virtualenv,请务必在其中运行命令。

\n

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

\n

为了支持 TLS 1.1 或更高版本,您可能需要安装较新版本的 OpenSSL,然后再次安装 Python。这将为您提供支持 TLS 1.1 的 Python。

\n

该过程取决于您的操作系统 \xe2\x80\x93 这里是OS X指南。

\n

virtualenv 用户
\n对于我来说,virtualenv 之外的 Python 支持 TLS 1.2,因此我只需删除旧的 virtualenv,并使用相同的包创建一个新的 virtualenv,然后它就可以工作了。十分简单!

\n

  • 从命令行进行一行检查: `python -c "from urllib.request import urlopen ; print(urlopen('https://www.howsmyssl.com/a/check').read())"` (3认同)

A G*_*A G 16

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

我通过这样做解决了这个问题

unset https_proxy
Run Code Online (Sandbox Code Playgroud)


giv*_*rld 9

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

pip install ndg-httpsclient

pip install pyopenssl

pip install pyasn1
Run Code Online (Sandbox Code Playgroud)

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

希望能帮助到你.

  • 我投了反对票,因为它对我没有任何帮助。我猜这些库的下载统计数据无缘无故地上升了 oo (6认同)
  • 这对我没有任何帮助。 (2认同)

Jam*_*Lin 5

我遇到了完全相同的错误,原来是我没有ndg-httpsclient安装,请参阅我在 github 中提出的原始问题

  • 链接已删除:/ (4认同)

hug*_*own 2

我唯一一次看到这种性质的错误是在我使用requests多处理库来筛选数据时。我要么在没有池管理器的情况下尝试您的代码,要么将您的应用程序分成两个应用程序,一个分发网址,另一个使用它们。

这里的客户端-服务器对应该会给你一些想法。当我之前使用 hacky 服务器代码将所有 url 加载到内存中的队列中时,我能够水平扩展我的客户端app.run。希望有帮助。