7

でhttps://yande.re/を開いて読みたいurllib.requestのですが、SSLエラーが出てしまいます。http.clientこのコードを使用して、ページを開いて読むことができます。

import http.client

conn = http.client.HTTPSConnection('www.yande.re')
conn.request('GET', 'https://yande.re/')
resp = conn.getresponse()
data = resp.read()

ただし、次のコードを使用するとurllib.request失敗します。

import urllib.request

opener = urllib.request.build_opener()
resp = opener.open('https://yande.re/')
data = resp.read()

次のエラーが表示されますssl.SSLError: [Errno 1] _ssl.c:392: error:1411809D:SSL routines:SSL_CHECK_SERVERHELLO_TLSEXT:tls invalid ecpointformat list。HTTPSConnection でページを開くことができるのに、opener.open で開くことができないのはなぜですか?

編集:これが私の OpenSSL バージョンと、https: //yande.re/ を開こうとしたときのトレースバックです。

>>> import ssl; ssl.OPENSSL_VERSION
'OpenSSL 1.0.0a 1 Jun 2010'
>>> import urllib.request
>>> urllib.request.urlopen('https://yande.re/')
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    urllib.request.urlopen('https://yande.re/')
  File "C:\Python32\lib\urllib\request.py", line 138, in urlopen
    return opener.open(url, data, timeout)
  File "C:\Python32\lib\urllib\request.py", line 369, in open
    response = self._open(req, data)
  File "C:\Python32\lib\urllib\request.py", line 387, in _open
    '_open', req)
  File "C:\Python32\lib\urllib\request.py", line 347, in _call_chain
    result = func(*args)
  File "C:\Python32\lib\urllib\request.py", line 1171, in https_open
    context=self._context, check_hostname=self._check_hostname)
  File "C:\Python32\lib\urllib\request.py", line 1138, in do_open
    raise URLError(err)
urllib.error.URLError: <urlopen error [Errno 1] _ssl.c:392: error:1411809D:SSL routines:SSL_CHECK_SERVERHELLO_TLSEXT:tls invalid ecpointformat list>
>>> 
4

4 に答える 4

2

これは、楕円曲線暗号の初期の1.xOpenSSL実装のバグが原因です。例外の関連部分を詳しく見てみましょう。

_ssl.c:392: error:1411809D:SSL routines:SSL_CHECK_SERVERHELLO_TLSEXT:tls invalid ecpointformat list

これは、ECポイント形式のTLS拡張を誤って処理した結果である、基になるOpenSSLライブラリコードからのエラーです。1つの回避策は、SSLv23メソッドの代わりにSSLv3を使用することです。もう1つの回避策は、すべてのECC暗号スイートを無効にする暗号スイート仕様を使用することです(テストALL:-ECDHに使用すると、良好な結果が得られました)。openssl ciphers修正はOpenSSLを更新することです。

于 2012-12-20T16:30:29.263 に答える
2

なんという偶然なんでしょう!私はあなたと同じ問題を抱えていますが、さらに複雑です。私はプロキシの背後にいます。https-not-working-with-urllib に関するこのバグ レポートを見つけました。幸いなことに、彼らは回避策を投稿しました。

import urllib.request
import ssl

##uncomment this code if you're behind a proxy
##https port is 443 but it doesn't work for me, used port 80 instead

##proxy_auth = '{0}://{1}:{2}@{3}'.format('https', 'username', 'password', 
##             'proxy:80')
##proxies = { 'https' : proxy_auth }
##proxy = urllib.request.ProxyHandler(proxies)
##proxy_auth_handler = urllib.request.HTTPBasicAuthHandler()
##opener = urllib.request.build_opener(proxy, proxy_auth_handler, 
##                                     https_sslv3_handler)

https_sslv3_handler = 
         urllib.request.HTTPSHandler(context=ssl.SSLContext(ssl.PROTOCOL_SSLv3))
opener = urllib.request.build_opener(https_sslv3_handler)
urllib.request.install_opener(opener)
resp = opener.open('https://yande.re/')
data = resp.read().decode('utf-8')
print(data)

ところで、使用方法を示してくれてありがとうhttp.client。インターネットに接続するために使用できる別のライブラリがあることを知りませんでした。;)

于 2012-12-04T05:25:57.940 に答える
1

問題は、2 つの例で指定したホスト名が原因です。

import http.client
conn = http.client.HTTPSConnection('www.yande.re')
conn.request('GET', 'https://yande.re/')

と...

import urllib.request
urllib.request.urlopen('https://yande.re/')

最初の例では、クライアントにホスト www.yande.re への接続を要求していることに注意してください。2 番目の例では、urllib は最初に URL 'https://yande.re' を解析してから試行します。ホスト yande.re でのリクエスト

www.yande.re と yande.re は同じ IP アドレスに解決される場合がありますが、Web サーバーの観点からは、これらは異なる仮想ホストです。私の推測では、Web サーバー側でSNI構成に問題があったと思われます。元の質問が 5 月 21 日に投稿され、yande.re の現在の証明書が 5 月 28 日に開始されたことを見て、この問題は既に修正されていると思いますか?

于 2012-05-30T18:47:31.240 に答える
-1

これを試して:

import connection #imports connection
import url 

url = 'http://www.google.com/'    
webpage = url.open(url)

try:
    connection.receive(webpage)
except:
    webpage = url.text('This webpage is not available!')
    connection.receive(webpage)
于 2012-08-22T15:15:55.530 に答える