我在 Python 2.7.10 下使用 urllib2 连接 https 时遇到问题。
有什么想法我想念的吗?
Python 2.7.10 (default, Jun 18 2015, 10:53:24)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import ssl, urllib2
>>> ssl.HAS_SNI
True
>>> ssl.OPENSSL_VERSION
'OpenSSL 0.9.8o 01 Jun 2010'
>>> opener = urllib2.build_opener()
>>> opener.open('https://twitrss.me/')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/python2.7/lib/python2.7/urllib2.py", line 431, in open
response = self._open(req, data)
File "/usr/local/python2.7/lib/python2.7/urllib2.py", line 449, in _open
'_open', req)
File "/usr/local/python2.7/lib/python2.7/urllib2.py", line 409, in _call_chain
result = func(*args)
File "/usr/local/python2.7/lib/python2.7/urllib2.py", line 1240, in https_open
context=self._context)
File "/usr/local/python2.7/lib/python2.7/urllib2.py", line 1197, in do_open
raise URLError(err)
urllib2.URLError: <urlopen error [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:590)>
最佳答案
我能够在 OS X 10.10.3 上重现您的问题,其现有 Python 是使用 OpenSSL 0.9.8zd 构建的 2.7.6。
问题是缺少 Server Name Indication TLS 握手中的 (SNI) 扩展,twitrss.me 网站显然需要:
Server Name Indication (SNI) is an extension to the TLS computer networking protocol by which a client indicates which hostname it is attempting to connect to at the start of the handshaking process.
我通过使用 OpenSSL 编写一个小的 C++ 程序并插入 OpenSSL 调用来验证这一点
SSL_set_tlsext_host_name(ssl, "twitrss.me");
允许成功连接,而忽略则失败。我还查看了数据包转储,以验证在尝试使用 Python 进行连接时是否缺少 SNI。
显然是 Python SSL 模块 supports SNI in Python 3但是may require a workaround in Python 2 .看来 PEP 0466包括 SNI 并登陆 Python 2.7.9,所以你应该拥有它,但我不知道 urllib2/urllib3
是否在没有解决方法的情况下利用它。
关于python - SSLv3 警告与 urllib2 的握手失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30918761/