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

use*_*902 7 python ssl https urllib

我想打开并阅读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()
Run Code Online (Sandbox Code Playgroud)

但是,以下代码使用urllib.request失败:

import urllib.request

opener = urllib.request.build_opener()
resp = opener.open('https://yande.re/')
data = resp.read()
Run Code Online (Sandbox Code Playgroud)

它给了我以下错误: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>
>>> 
Run Code Online (Sandbox Code Playgroud)

par*_*uth 1

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

import http.client
conn = http.client.HTTPSConnection('www.yande.re')
conn.request('GET', 'https://yande.re/')
Run Code Online (Sandbox Code Playgroud)

和...

import urllib.request
urllib.request.urlopen('https://yande.re/')
Run Code Online (Sandbox Code Playgroud)

请注意,在第一个示例中,您要求客户端与主机建立连接: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 日开始,我认为您已经解决了这个问题?