web-dev-qa-db-ja.com

Python requests.exceptions.SSLError:EOFプロトコルに違反して発生しました

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でリクエスト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)

私はこの問題にこだわっています。誰かが私を助けることができますか?ありがとう!

9
mzilio

このことは私にとってはうまくいきました。これらのモジュールがインストールされているかどうかを確認してください。そうでない場合は、以下をインストールしてください:

pip install ndg-httpsclient

pip install pyopenssl

pip install pyasn1

SSLError:EOFプロトコル違反(_ssl.c:590)エラーで発生しました)を削除しました。

それが役に立てば幸い。

9

まったく同じエラーが発生しましたが、ndg-httpsclientインストール済み、元の issue githubで発生したものを参照してください。

3
James Lin

サーバーに直接接続する必要があるときに、プロキシを経由していたことがわかりました。

私はこれを修正しました

unset https_proxy
2
A G

ステップ1:PythonがTLS 1.1をサポートしていることを確認します

Pythonセットアップは、TLS 1.0のみをサポートし、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.1ではなくTLS 1.2と表示されている場合は、問題の可能性があります。

Virtualenvを使用している場合は、必ず内部でコマンドを実行してください。

ステップ2:OpenSSLの新しいバージョンでPythonをインストールする

TLS 1.1以上をサポートするには、新しいバージョンのOpenSSLをインストールし、その後で再度Pythonをインストールする必要がある場合があります。これにより、TLS 1.1をサポートするPythonが得られます。

プロセスはオペレーティングシステムによって異なります。ここに OS X のガイドがあります。

virtualenvユーザー
私にとっては、virtualenvの外部のPythonはTLS 1.2をサポートしていたため、古いvirtualenvを削除し、同じパッケージを使用して新しいvirtualenvを作成しました。簡単!

1
qff

中間リクエストでこのエラーが発生する場合は、 https://github.com/requests/requests/issues/3391 に記載されている解決策を参照してください。

基本的に、サーバーに対して多くのリクエストを作成し、それらのリクエストの一部でこの問題に直面している場合、Sessionを使用してリクエストを再試行することができます。

これが機能するかどうかを教えてください。

1
varun

この種のエラーを目にしたのは、requestsを使用してスクレイプデータを選別し、マルチプロセッシングライブラリを使用していたときだけです。プールマネージャーなしでコードを試すか、アプリを2つのアプリに分割します。1つはURLを削除し、もう1つはそれらを使用します。

クライアントとサーバーのペア here からアイデアが得られるはずです。 app.runの直前に、ハッキングサーバーコードを使用してすべてのURLをメモリ内のキューに読み込むと、クライアントを水平方向にスケールアウトできました。お役に立てば幸いです。

0
hughdbrown