python打开https_在Python 3.2中,我可以使用http.client打开和读取HTTPS网页,但是urllib.request无法打开同一页面...

I want to open and read https://yande.re/ with urllib.request, but I'm getting an SSL error. I can open and read the page just fine using http.client with this code:

import http.client

conn = http.client.HTTPSConnection('www.yande.re')

conn.request('GET', 'https://yande.re/')

resp = conn.getresponse()

data = resp.read()

However, the following code using urllib.request fails:

import urllib.request

opener = urllib.request.build_opener()

resp = opener.open('https://yande.re/')

data = resp.read()

It gives me the following error: ssl.SSLError: [Errno 1] _ssl.c:392: error:1411809D:SSL routines:SSL_CHECK_SERVERHELLO_TLSEXT:tls invalid ecpointformat list. Why can I open the page with HTTPSConnection but not opener.open?

Edit: Here's my OpenSSL version and the traceback from trying to open 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 "", line 1, in

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:

>>>

解决方案

This is due to a bug in the early 1.x OpenSSL implementation of elliptic curve cryptography. Take a closer look at the relevant part of the exception:

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

This is an error from the underlying OpenSSL library code which is a result of mishandling the EC point format TLS extension. One workaround is to use the SSLv3 instead of SSLv23 method, the other workaround is to use a cipher suite specification which disables all ECC cipher suites (I had good results with ALL:-ECDH, use openssl ciphers for testing). The fix is to update OpenSSL.