2017-08-16 75 views
1

代码应用如何使用python 3中的urllib请求解决SSL握手失败?

嗨堆垛机,我设计一个网站刮板发送通知基于特定的基于词的标准的用户。我已经成功地在一个测试网站上抓了一段时间,但是,当我昨天去运行我的代码时,出现了一个意外的错误,我一直未能解决问题。我仍然不确定为什么这个错误发生,因为我的代码中没有任何改变 - 这导致我相信网站的某些内容可能已经改变。当我在使用urllib的请求后尝试读取网站的内容时,出现错误。

守则

url = "http://www.ksl.com" 

import urllib.request 
from urllib.request import Request, urlopen 
from bs4 import BeautifulSoup 

import ssl 
print(ssl.OPENSSL_VERSION) 

req = Request(url, headers={'User-Agent': 'Mozilla/5.0'}) 
html = urlopen(req).read() 
html = html.decode('utf-8') 

错误消息

Traceback (most recent call last): 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/urllib/request.py", line 1254, in do_open 
    h.request(req.get_method(), req.selector, req.data, headers) 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/http/client.py", line 1106, in request 
    self._send_request(method, url, body, headers) 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/http/client.py", line 1151, in _send_request 
    self.endheaders(body) 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/http/client.py", line 1102, in endheaders 
    self._send_output(message_body) 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/http/client.py", line 934, in _send_output 
    self.send(msg) 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/http/client.py", line 877, in send 
    self.connect() 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/http/client.py", line 1260, in connect 
    server_hostname=server_hostname) 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ssl.py", line 377, in wrap_socket 
    _context=self) 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ssl.py", line 752, in __init__ 
    self.do_handshake() 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ssl.py", line 988, in do_handshake 
    self._sslobj.do_handshake() 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ssl.py", line 633, in do_handshake 
    self._sslobj.do_handshake() 
ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:645) 

During handling of the above exception, another exception occurred: 

Traceback (most recent call last): 
    File "PATH TO SCRIPT", line 59, in <module> 
    html = urlopen(req).read() 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/urllib/request.py", line 163, in urlopen 
    return opener.open(url, data, timeout) 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/urllib/request.py", line 472, in open 
    response = meth(req, response) 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/urllib/request.py", line 582, in http_response 
    'http', request, response, code, msg, hdrs) 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/urllib/request.py", line 504, in error 
    result = self._call_chain(*args) 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/urllib/request.py", line 444, in _call_chain 
    result = func(*args) 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/urllib/request.py", line 696, in http_error_302 
    return self.parent.open(new, timeout=req.timeout) 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/urllib/request.py", line 466, in open 
    response = self._open(req, data) 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/urllib/request.py", line 484, in _open 
    '_open', req) 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/urllib/request.py", line 444, in _call_chain 
    result = func(*args) 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/urllib/request.py", line 1297, in https_open 
    context=self._context, check_hostname=self._check_hostname) 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/urllib/request.py", line 1256, in do_open 
    raise URLError(err) 
urllib.error.URLError: <urlopen error [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:645)> 

尝试我做了修复错误

所以我已经安装了MacPorts的企图更改python使用的SSL路径g,这不起作用,我不确定这是否是正确的解决方案路径。

我把这两行代码中看到的是实际上做什么蟒蛇:

v = sys.version 
print(v) 

import ssl 
print(ssl.OPENSSL_VERSION) 

这两行给我下面的输出:

3.5.2 (v3.5.2:4def2a2901a5, Jun 26 2016, 10:47:25) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] 
OpenSSL 0.9.8zh 14 Jan 2016 

我认为这个问题可能是python使用的是默认的OpenSSL版本,无法完成握手,但是我仍然有很多东西需要了解,所以我不完全确定。

请帮我堆垛机,你是我唯一的希望!

回答

0

是的,你的OpenSSL版本太旧了。下面是使用Mac系统的openssl的两个版本的例子:

$ openssl s_client -connect ksl.com:443 
CONNECTED(00000003) 
2908:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-64.50.6/src/ssl/s23_clnt.c:593: 

$ /usr/local/Cellar/openssl/1.0.2l/bin/openssl s_client -connect ksl.com:443 
[...] 
Verify return code: 0 (ok) 

如果你安装python的一个新版本,例如与brew install python3,你应该有更好的运气:

Python 3.6.2 (default, Jul 17 2017, 16:44:45) 
[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.42)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import ssl 
>>> ssl.OPENSSL_VERSION 
'OpenSSL 1.0.2l 25 May 2017' 

在这个版本中,你的脚本工作得很好。

+0

嘿基督教谢谢你的回应!我成功地在终端中运行了“brew install python3”命令,但它似乎没有更新我拥有的OpenSSL版本(它仍然在打印相同版本)。我认为这与$ PATH中的事物顺序有关,但我不知道如何解决它。 – Whodo