Je reçois l'erreur suivante:
Exception in thread Thread-3:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "/Users/Matthew/Desktop/Skypebot 2.0/bot.py", line 271, in process
info = urllib2.urlopen(req).read()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 154, in urlopen
return opener.open(url, data, timeout)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 431, in open
response = self._open(req, data)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 449, in _open
'_open', req)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 409, in _call_chain
result = func(*args)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 1240, in https_open
context=self._context)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 1197, in do_open
raise URLError(err)
URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)>
C'est le code qui cause cette erreur:
if input.startswith("!web"):
input = input.replace("!web ", "")
url = "https://domainsearch.p.mashape.com/index.php?name=" + input
req = urllib2.Request(url, headers={ 'X-Mashape-Key': 'XXXXXXXXXXXXXXXXXXXX' })
info = urllib2.urlopen(req).read()
Message.Chat.SendMessage ("" + info)
L'API que j'utilise nécessite l'utilisation de HTTPS. Comment puis-je le faire contourner la vérification?
Si vous juste souhaitez ignorer la vérification, vous pouvez créer un nouveau SSLContext . Par défaut, les contextes nouvellement créés utilisent CERT_NONE .
Soyez prudent avec ceci comme indiqué dans la section 17.3.7.2.1
Lorsque vous appelez directement le constructeur SSLContext, CERT_NONE est la valeur par défaut. Dans la mesure où il n'authentifie pas l'autre homologue, il peut s'avérer peu sûr, en particulier en mode client, où vous souhaitez la plupart du temps garantir l'authenticité du serveur avec lequel vous parlez. Par conséquent, en mode client, il est vivement recommandé d'utiliser CERT_REQUIRED.
Mais si vous voulez simplement que cela fonctionne maintenant pour une autre raison, vous devez procéder de la manière suivante: import ssl
:
input = input.replace("!web ", "")
url = "https://domainsearch.p.mashape.com/index.php?name=" + input
req = urllib2.Request(url, headers={ 'X-Mashape-Key': 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' })
gcontext = ssl.SSLContext() # Only for gangstars
info = urllib2.urlopen(req, context=gcontext).read()
Message.Chat.SendMessage ("" + info)
Cela devrait résoudre votre problème, mais vous ne résolvez pas vraiment tous les problèmes, mais vous ne verrez pas le [SSL: CERTIFICATE_VERIFY_FAILED]
car vous ne vérifiez pas le certificat!
Pour ajouter à ce qui précède, si vous souhaitez en savoir plus sur les raisons de ces problèmes, vous pouvez consulter/ PEP 476 .
Ce PEP propose d'activer la vérification des signatures de certificat X509, ainsi que la vérification du nom d'hôte pour les clients HTTP de Python par défaut, sous réserve d'une option de retrait par appel. Cette modification serait appliquée à Python 2.7, Python 3.4 et Python 3.5.
Il y a une option de retrait conseillée qui n'est pas différente de mon conseil ci-dessus:
import ssl
# This restores the same behavior as before.
context = ssl._create_unverified_context()
urllib.urlopen("https://no-valid-cert", context=context)
Il comporte également une option fortement déconseillée via monkeypatching que vous ne voyez pas souvent en python:
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
Ce qui remplace la fonction par défaut pour la création de contexte avec la fonction pour créer un contexte non vérifié.
Veuillez noter ceci comme indiqué dans le PEP:
Ce guide s'adresse principalement aux administrateurs système qui souhaitent adopter des versions plus récentes de Python qui implémentent ce PEP dans des environnements hérités qui ne prennent pas encore en charge la vérification de certificat sur les connexions HTTPS. Par exemple, un administrateur peut choisir de ne pas participer en ajoutant le monkeypatch ci-dessus à sitecustomize.py dans son environnement d'exploitation standard pour Python. Les applications et les bibliothèques NE DEVRAIENT PAS élargir ce processus de modification (sauf peut-être en réponse à un paramètre de configuration contrôlé par l'administrateur système).
Si vous voulez lire un article sur pourquoi ne pas valider les certificats est mauvais dans le logiciel vous pouvez le trouver ici !
Ce n'est pas une solution à votre problème spécifique, mais je le mets ici car ce fil est le premier résultat de Google pour "SSL: CERTIFICATE_VERIFY_FAILED", et il me conduit à la poursuite de l'oie sauvage.
Si vous avez installé Python 3.6 sur OSX et obtenez le message d'erreur "SSL: CERTIFICATE_VERIFY_FAILED" lorsque vous essayez de vous connecter à un site https: //, c'est probablement parce que Python 3.6 sur OSX n'a aucun certificat et ne peut valider aucun certificat SSL. les liaisons. Cette modification de la version 3.6 sous OSX nécessite une étape de post-installation, qui installe le paquet de certificats certifi
. Ceci est documenté dans le ReadMe, que vous devriez trouver à /Applications/Python\ 3.6/ReadMe.rtf
Le fichier Lisezmoi vous demandera d’exécuter ce script de post-installation, qui installe simplement certifi
: /Applications/Python\ 3.6/Install\ Certificates.command
Les notes de publication contiennent des informations supplémentaires: https://www.python.org/downloads/release/python-360/
Pour développer la réponse de Craig Glennie (désolé, pas assez de réputation pour commenter):
en Python 3.6.1 sur MacOs Sierra
Entrer cela dans le terminal bash a résolu le problème:
pip install certifi
/Applications/Python\ 3.6/Install\ Certificates.command
Sous Windows, Python ne regarde pas le certificat système, il utilise son propre répertoire situé à ?\lib\site-packages\certifi\cacert.pem
.
La solution à votre problème:
cacert.pem
emplacement: from requests.utils import DEFAULT_CA_BUNDLE_PATH; print(DEFAULT_CA_BUNDLE_PATH)
cacert.pem
et collez votre certificat de validation de domaine à la fin du fichier.Ma solution pour Mac OS X:
1) Mettez à niveau vers Python 3.6.5 à l’aide du programme d’installation natif de l’application Python téléchargé à partir du site Web officiel du langage Python https://www.python.org/downloads/
J'ai constaté que ce programme d'installation s'occupe de la mise à jour des liens et des liens symboliques pour le nouveau Python bien mieux qu'homebrew.
2) Installez un nouveau certificat en utilisant "./Install Certificates.command" qui se trouve dans le répertoire Python 3.6 actualisé.
> cd "/Applications/Python 3.6/"
> Sudo "./Install Certificates.command"
Vous pouvez essayer d'ajouter ceci à vos variables d'environnement:
PYTHONHTTPSVERIFY=0
Notez que ceci désactivera tout la vérification HTTP est donc un peu une approche de sledgehammer, cependant si la vérification n'est pas requise, cela peut être une solution efficace.
J'avais un problème similaire, bien que j'utilisais urllib.request.urlopen
dans Python 3.4, 3.5 et 3.6. (Ceci est une partie de l'équivalent Python 3 de urllib2
, comme indiqué dans l'en-tête de la page de documentation urllib2
de Python 2 .)
Ma solution était de pip install certifi
pour installer certifi
, qui a:
... une collection soigneusement organisée de certificats racine permettant de valider la fiabilité des certificats SSL lors de la vérification de l'identité des hôtes TLS.
Ensuite, dans mon code où je venais tout juste de commencer:
import urllib.request as urlrq
resp = urlrq.urlopen('https://foo.com/bar/baz.html')
Je l'ai révisé pour:
import urllib.request as urlrq
import certifi
resp = urlrq.urlopen('https://foo.com/bar/baz.html', cafile=certifi.where())
Si je lis correctement la documentation urllib2.urlopen
, elle contient également un argument cafile
. Donc, urllib2.urlopen([...], certifi.where())
pourrait également fonctionner pour Python 2.7.
import requests
requests.packages.urllib3.disable_warnings()
import ssl
try:
_create_unverified_https_context = ssl._create_unverified_context
except AttributeError:
# Legacy Python that doesn't verify HTTPS certificates by default
pass
else:
# Handle target environment that doesn't support HTTPS verification
ssl._create_default_https_context = _create_unverified_https_context
Tiré d'ici https://Gist.github.com/michaelrice/a6794a017e349fc65d01
Comme je l'ai écrit dans un commentaire, ce problème est probablement lié à cette SO réponse .
En bref: il existe plusieurs façons de vérifier le certificat. La vérification utilisée par OpenSSL est incompatible avec les certificats racine de confiance que vous avez sur votre système. OpenSSL est utilisé par Python.
Vous pouvez essayer d'obtenir le certificat manquant pour Autorité de certification principale publique de classe 3 de Verisign puis utiliser l'option cafile
selon la documentation de Python :
urllib2.urlopen(req, cafile="verisign.pem")
Pour Python 3.4+ on Centos 6/7, Fedora , installez simplement l'autorité de certification approuvée de cette manière:
/etc/pki/ca-trust/source/anchors/
update-ca-trust force-enable
update-ca-trust extract
Je dois ajouter une autre réponse car, tout comme Craig Glennie, je me suis lancé à la poursuite de l'oie sauvage en raison des nombreux messages faisant référence à ce problème sur le Web.
J'utilise MacPorts, et ce que je pensais à l'origine comme un problème de Python était en fait un problème de MacPorts: il n'installe pas de certificat racine avec son installation d'OpenSL. La solution consiste à port install curl-ca-bundle
, comme indiqué dans cet article de blog .
Je me bloque à moitié, car j'avais le même problème, sauf que dans mon cas, l'URL que je frappais était valide, le certificat était valide. Ce qui n’était pas valable c’était ma connexion au Web. J'avais échoué à ajouter des détails de proxy dans le navigateur (IE dans ce cas). Cela a empêché le processus de vérification de se dérouler correctement.
Ajouté dans les détails du proxy et mon python était alors très heureux.
Je suis surpris que toutes ces instructions n'aient pas résolu mon problème. Néanmoins, le diagnostic est correct (BTW, j'utilise Mac et Python3.6.1). Donc, pour résumer la bonne partie:
Pour moi, le script ne fonctionne pas, et toutes ces installations de certifi et openssl ont échoué. Peut-être parce que j'ai plusieurs installations Python 2 et 3, ainsi que de nombreuses virtualenv. À la fin, je dois le réparer à la main.
pip install certifi # for your virtualenv
mkdir -p /Library/Frameworks/Python.framework/Versions/3.6/etc/openssl
cp -a <your virtualenv>/site-package/certifi/cacert.pem \
/Library/Frameworks/Python.framework/Versions/3.6/etc/openssl/cert.pem
Si cela vous échoue encore. Ensuite, réinstallez OpenSSL.
port install openssl
Comme vous, j'utilise python 2.7 sur mon ancien iMac (OS X 10.6.8), j'ai également rencontré le problème en utilisant urllib2.urlopen:
urlopen error [SSL: CERTIFICATE_VERIFY_FAILED]
Mes programmes fonctionnaient correctement sans problèmes de certificat SSL et soudainement (après le téléchargement des programmes), ils se sont écrasés avec cette erreur SSL.
Le problème était la version de python utilisée:
Pas de problème avec https://www.python.org/downloads et python-2.7.9-macosx10.6.pkg
problème avec celui installé par Outil Homebrew : "brew install python", version située dans/usr/local/bin.
Un chapitre, appelé Certificate verification and OpenSSL [CHANGED for Python 2.7.9]
, dans /Applications/Python 2.7/ReadMe.rtf
explique le problème avec de nombreux détails.
Alors, vérifiez, téléchargez et mettez dans votre PATH la bonne version de python.
Essayer
pip install --trusted-Host pypi.python.org nom_package
Cela a fonctionné pour moi.
Jeter un coup d'œil à
/ Applications/Python 3.6/Install Certificates.command
Vous pouvez également aller à Applications et cliquer sur Certificates.command
Python 2.7.12 (défaut, le 29 juillet 2016, 15:26:22) a corrigé le problème mentionné. Cette information pourrait aider quelqu'un d'autre.
Pour ceux qui utilisent mechanize
et rencontrent cette question, voici comment appliquer la même technique à une instance de mécanisation Browser:
br = mechanize.Browser()
context = ssl._create_unverified_context()
br.set_ca_data(context=context)
Si vous utilisez vCenter 6, vous devriez plutôt ajouter votre certificat d'autorité de certification vmware de vCenter à la liste des autorités de certification approuvées de votre système d'exploitation. Pour télécharger votre certificat, procédez comme suit
Sur Fedora
Liens:
Déjà beaucoup de réponses ici, mais nous avons rencontré cela dans un cas très spécifique et avons perdu beaucoup de temps à enquêter, donc en ajoutant encore un autre. Nous l'avons vu dans le cas suivant:
easy_install3
Les commandes pip3
et openssl
ont toutes deux été en mesure de vérifier le certificat et easy_install3
a pu vérifier les autres certificats LetsEncrypt avec succès.
La solution de contournement consistait à générer la dernière version de Python (3.7.3 à l’époque) à partir des sources. Les instructions ici sont détaillées et faciles à suivre.
Dans mon cas, cette erreur me causait parce que les versions de requests
et urllib3
étaient incompatibles, donnant l'erreur suivante lors de l'installation:
ERROR: requests 2.21.0 has requirement urllib3<1.25,>=1.21.1, but you'll have urllib3 1.25 which is incompatible.
pip install 'urllib3<1.25' --force-reinstall
a fait le tour.
En python 2.7, ajouter les détails de l'autorité de certification racine approuvée à la fin du fichier C:\Python27\lib\site-packages\certifi\cacert.pem
après cela, j'ai exécuté (avec les droits d'administrateur) pip install
Pour Linux Python3.6, cela a fonctionné pour moi.
depuis la ligne de commande, installez pyopenssl et certifi
Sudo pip3 install -U pyopenssl
Sudo pip3 install certifi
et dans mon script python3, ajouté verify = '/ usr/lib/python3.6/site-packages/certifi/cacert.pem' ainsi:
import requests
from requests.auth import HTTPBasicAuth
import certifi
auth = HTTPBasicAuth('username', 'password')
body = {}
r = requests.post(url='https://your_url.com', data=body, auth=auth, verify='/usr/lib/python3.6/site-packages/certifi/cacert.pem')
Python 2.7 sur Amazon EC2 avec centOS 7
Je devais définir la variable env SSL_CERT_DIR
pour qu'elle pointe vers mon ca-bundle
situé à /etc/ssl/certs/ca-bundle.crt
J'ai trouvé ceci sur ici
J'ai trouvé cette solution, insérez ce code au début de votre fichier source:
import ssl
try:
_create_unverified_https_context = ssl._create_unverified_context
except AttributeError:
# Legacy Python that doesn't verify HTTPS certificates by default
pass
else:
# Handle target environment that doesn't support HTTPS verification
ssl._create_default_https_context = _create_unverified_https_context
Ce code annule la vérification afin que la certification SSL ne soit pas vérifiée.
Sudo easy_install pip
utiliser l'option Ignorer les installations pour ignorer la désinstallation de la version précédente de six
Sudo pip3 install -U nltk --ignore-installed six
Vérifiez l'installation de pip et python, utilisez les versions '3'
which python python2 python3
which pip pip2 pip3
Vérifier si NLTK est installé
python3
import nltk
nltk.__path__
['/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/nltk']
Installez le certificat SSL avant d'installer le livre d'exemples, sinon nous aurons une erreur de certificat lors de l'installation des exemples
/Applications/Python\ 3.6/Install\ Certificates.command
python3 -m nltk.downloader book
L'installation de nltk et nltk_ata pour des exemples de livre a été effectuée avec succès.
Ma configuration est Anaconda Python 3.7 sur MacOS avec un proxy. Les chemins sont différents.
import ssl
ssl.get_default_verify_paths()
qui sur mon système produit
Out[35]: DefaultVerifyPaths(cafile='/miniconda3/ssl/cert.pem', capath=None,
openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/miniconda3/ssl/cert.pem',
openssl_capath_env='SSL_CERT_DIR', openssl_capath='/miniconda3/ssl/certs')
Une fois que vous savez où se trouve le certificat, vous concatérez le certificat utilisé par le proxy à la fin de ce fichier.
J'avais déjà configuré conda pour travailler avec mon proxy en lançant:
conda config --set ssl_verify <pathToYourFile>.crt
Si vous ne vous rappelez pas où se trouve votre certificat, vous pouvez le trouver dans ~/.condarc
:
ssl_verify: <pathToYourFile>.crt
Maintenant, concaténer} _ ce fichier à la fin de /miniconda3/ssl/cert.pem
et les demandes devraient fonctionner, et en particulier sklearn.datasets
et des outils similaires devraient fonctionner.
Les autres solutions n'ont pas fonctionné car la configuration d'Anaconda est légèrement différente:
Le chemin Applications/Python\ 3.X
n'existe tout simplement pas.
Le chemin fourni par les commandes ci-dessous est leMAUVAISchemin
from requests.utils import DEFAULT_CA_BUNDLE_PATH
DEFAULT_CA_BUNDLE_PATH
Installer PyOpenSSL
en utilisant pip
a fonctionné pour moi (sans conversion en PEM):
pip install PyOpenSSL
J'ai eu ce problème résolu en fermant Fiddler (un proxy de débogage HTTP), vérifiez si un proxy est activé et essayez à nouveau.
L'installation de certifi sur Mac a résolu mon problème:
pip install certifi
Une autre solution d'Anaconda. J'obtenais CERTIFICATE_VERIFY_FAILED dans mon environnement Python 2.7 sous macOS. Il s'avère que les chemins conda étaient mauvais:
environnement de base (3.7):
>>> import ssl
>>> ssl.get_default_verify_paths()
DefaultVerifyPaths(cafile='/usr/local/anaconda3/ssl/cert.pem', capath=None, openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/usr/local/anaconda3/ssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/usr/local/anaconda3/ssl/certs')
2.7 environnement (les chemins n'existaient pas!):
DefaultVerifyPaths(cafile='', capath=None, openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/usr/local/anaconda3/envs/py27/ssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/usr/local/anaconda3/envs/py27/ssl/certs')
Le correctif:
cd /usr/local/anaconda3/envs/py27/
mkdir ssl
cd ssl
ln -s ../../../ssl/cert.pem