我使用代理(在公司防火墙后面)登录https域。 SSL握手似乎进展顺利:
CertificateError: hostname 'ats.finra.org:443' doesn't match 'ats.finra.org'
我使用的是Python 2.7.9 - Mechanize并且我已经通过了所有的登录,密码和安全问题屏幕,但它已经挂了认证。
任何帮助都会很棒。我已经尝试过在这里找到的Monkeywrench:Forcing Mechanize to use SSLv3
虽然不适用于我的代码。
如果您想要代码文件,我很乐意发送。
答案 0 :(得分:16)
你可以通过猴子修补ssl来避免这个错误:
import ssl
ssl.match_hostname = lambda cert, hostname: True
答案 1 :(得分:4)
ssl.math_hostname中的这个错误出现在v2.7.9中(它不在2.7.5中),并且与不从hostname:port语法中删除主机名有关。以下重写ssl.match_hostname修复了该错误。把它放在机械化代码之前:
import functools, re, urlparse
import ssl
old_match_hostname = ssl.match_hostname
@functools.wraps(old_match_hostname)
def match_hostname_bugfix_ssl_py_2_7_9(cert, hostname):
m = re.search(r':\d+$',hostname) # hostname:port
if m is not None:
o = urlparse.urlparse('https://' + hostname)
hostname = o.hostname
old_match_hostname(cert, hostname)
ssl.match_hostname = match_hostname_bugfix_ssl_py_2_7_9
现在应该使用以下机械化代码:
import mechanize
import cookielib
br = mechanize.Browser()
# Cookie Jar
cj = cookielib.LWPCookieJar()
br.set_cookiejar(cj)
# Browser options
br.set_handle_equiv(True)
br.set_handle_gzip(True)
br.set_handle_redirect(True)
br.set_handle_referer(True)
br.set_handle_robots(False)
# Follows refresh 0 but not hang on refresh > 0
br.set_handle_refresh(mechanize._http.HTTPRefreshProcessor(), max_time=1)
br.addheaders = [('User-Agent', 'Nutscrape 1.0')]
# Use this proxy
br.set_proxies({"http": "localhost:3128", "https": "localhost:3128"})
r = br.open('https://www.duckduckgo.com:443/')
html = br.response().read()
# Examine the html response from a browser
f = open('foo.html','w')
f.write(html)
f.close()
答案 2 :(得分:4)
在我的情况下,证书的DNS名称为::1
(用于本地测试目的),主机名验证失败,
ssl.CertificateError: hostname '::1' doesn't match '::1'
为了解决这个问题,我使用
修补ssl.match_hostname
import ssl
ssl.match_hostname = lambda cert, hostname: hostname == cert['subjectAltName'][0][1]
实际检查主机名是否匹配。