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.x OpenSSL 实现中的一个错误。仔细看看异常的相关部分:

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

这是来自底层 OpenSSL 库代码的错误,它是错误处理 EC 点格式 TLS 扩展的结果。一种解决方法是使用 SSLv3 而不是 SSLv23 方法,另一种解决方法是使用禁用所有 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

问题是由于您在两个示例中给出的主机名:

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,在第二个示例中,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 回答