J'utilise un proxy (derrière le pare-feu d'entreprise) pour me connecter à un domaine https. La prise de contact SSL ne semble pas bien se passer:
CertificateError: hostname 'ats.finra.org:443' doesn't match 'ats.finra.org'
J'utilise Python 2.7.9 - Mécanisez et j'ai dépassé tous les écrans de connexion, de mot de passe et de recherche de sécurité, mais cela se bloque sur la certification.
Toute aide serait incroyable. J'ai essayé le monkeywrench trouvé ici: Forcer Mechanize à utiliser SSLv
Ne fonctionne pas pour mon code cependant.
Si vous voulez le fichier de code, je serais heureux de l'envoyer.
Vous pouvez éviter cette erreur en réparant ssl par monkey:
import ssl
ssl.match_hostname = lambda cert, hostname: True
Ce bogue dans ssl.math_hostname apparaît dans la v2.7.9 (ce n'est pas dans 2.7.5), et a à voir avec ne pas supprimer le nom d'hôte de la syntaxe hostname: port. La réécriture suivante de ssl.match_hostname corrige le bogue. Mettez ceci avant votre code de mécanisation:
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
Le code de mécanisation suivant devrait maintenant fonctionner:
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()
Dans mon cas, le nom DNS du certificat était ::1
(À des fins de test local) et la vérification du nom d'hôte a échoué avec
ssl.CertificateError: hostname '::1' doesn't match '::1'
Pour le corriger un peu correctement, j'ai singé patché ssl.match_hostname
Avec
import ssl
ssl.match_hostname = lambda cert, hostname: hostname == cert['subjectAltName'][0][1]
Qui vérifie réellement si les noms d'hôte correspondent.