Urllib и "SSL: CERTIFICATE_VERIFY_FAILED" Ошибка
Я получаю следующую ошибку:
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)>
Это код, вызывающий эту ошибку:
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)
API, который я использую, требует использования HTTPS. Как я могу сделать это в обход проверки?
Ответы
Ответ 1
Если вы просто хотите обойти проверку, вы можете создать новый SSLContext. По умолчанию вновь созданные контексты используют CERT_NONE.
Будьте осторожны с этим, как указано в разделе 17.3.7.2.1
При непосредственном вызове конструктора SSLContext по умолчанию используется CERT_NONE. Поскольку он не аутентифицирует другого партнера, он может быть небезопасным, особенно в режиме клиента, где большую часть времени вы хотели бы обеспечить аутентичность сервера, с которым вы разговариваете. Поэтому в режиме клиента настоятельно рекомендуется использовать CERT_REQUIRED.
Но если вы просто хотите, чтобы он работал сейчас, по какой-то другой причине, вы можете сделать следующее, вам также придется 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)
Это должно обойти вашу проблему, но вы на самом деле не решаете ни одну из проблем, но вы не увидите [SSL: CERTIFICATE_VERIFY_FAILED]
потому что вы сейчас не проверяете сертификат!
Чтобы добавить к вышесказанному, если вы хотите узнать больше о том, почему вы видите эти проблемы, вы должны взглянуть на PEP 476.
В этом PEP предлагается включить проверку подписей сертификатов X509, а также проверку имени хоста для клиентов Python HTTP по умолчанию при условии отказа для каждого вызова. Это изменение будет применено к Python 2.7, Python 3.4 и Python 3.5.
Есть рекомендуемый отказ, который не отличается от моего совета выше:
import ssl
# This restores the same behavior as before.
context = ssl._create_unverified_context()
urllib.urlopen("https://no-valid-cert", context=context)
Он также имеет крайне обескураженную опцию с помощью monkeypatching, которую вы не часто видите в python:
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
Который переопределяет функцию по умолчанию для создания контекста с помощью функции для создания непроверенного контекста.
Обратите внимание на это, как указано в PEP:
Это руководство предназначено в первую очередь для системных администраторов, которые хотят использовать более новые версии Python, которые реализуют этот PEP в устаревших средах, которые еще не поддерживают проверку сертификатов для соединений HTTPS. Например, администратор может отказаться, добавив указанный выше обезьян-патч к sitecustomize.py в своей стандартной операционной среде для Python. Приложениям и библиотекам НЕ СЛЕДУЕТ делать этот процесс широким (за исключением, возможно, в ответ на настройки конфигурации, контролируемые системным администратором).
Если вы хотите прочитать статью о том, почему не проверка сертификатов плоха в программном обеспечении, вы можете найти ее здесь !
Ответ 2
Это не решение вашей конкретной проблемы, но я помещаю это здесь, потому что этот поток является лучшим результатом Google для "SSL: CERTIFICATE_VERIFY_FAILED", и это привело меня к безумной погоне за погоней.
Если вы установили Python 3.6 в OSX и получаете ошибку "SSL: CERTIFICATE_VERIFY_FAILED" при попытке подключиться к сайту https://, это, вероятно, связано с тем, что Python 3.6 в OSX вообще не имеет сертификатов и не может проверить любой SSL соединения. Это изменение для 3.6 в OSX, и оно требует шага после установки, который устанавливает пакет сертификатов certifi
. Это /Applications/Python\ 3.6/ReadMe.rtf
ReadMe, который вы должны найти в /Applications/Python\ 3.6/ReadMe.rtf
ReadMe предложит вам запустить этот скрипт после установки, который просто устанавливает certifi
: /Applications/Python\ 3.6/Install\ Certificates.command
Примечания к выпуску содержат дополнительную информацию: https://www.python.org/downloads/release/python-360/.
Ответ 3
Чтобы расширить ответ Крейга Гленни:
в Python 3.6.1 на MacOs Sierra
Ввод этого в терминале bash решил проблему:
pip install certifi
/Applications/Python\ 3.6/Install\ Certificates.command
Ответ 4
В Windows Python не смотрит на системный сертификат, он использует свой собственный, расположенный в ?\lib\site-packages\certifi\cacert.pem
.
Решение вашей проблемы:
- загрузить сертификат проверки домена как *.crt или * pem file
- откройте файл в редакторе и скопируйте его в буфер обмена
- найдите
cacert.pem
местоположение: from requests.utils import DEFAULT_CA_BUNDLE_PATH; print(DEFAULT_CA_BUNDLE_PATH)
- отредактируйте файл
cacert.pem
и вставьте сертификат проверки домена в конец файла.
- Сохраните файл и получите запросы!
Ответ 5
Мое решение для Mac OS X:
1) Обновление до Python 3.6.5 с помощью встроенного приложения Python, загруженного с официального сайта языка Python https://www.python.org/downloads/
Я обнаружил, что этот установщик заботится о обновлении ссылок и символических ссылок для нового Python намного лучше, чем homebrew.
2) Установите новый сертификат, используя "./Install Certificates.command", который находится в обновленном каталоге Python 3.6
> cd "/Applications/Python 3.6/"
> sudo "./Install Certificates.command"
Ответ 6
Вы можете попробовать добавить это к переменным среды:
PYTHONHTTPSVERIFY=0
Обратите внимание, что это отключит всю проверку HTTP, так что это немного подход к кувалде, но если проверка не требуется, это может быть эффективным решением.
Ответ 7
У меня была аналогичная проблема, хотя я использовал urllib.request.urlopen
в Python 3.4, 3.5 и 3.6. (Это часть эквивалента Python 3 urllib2
, за заметку во главе страницы документации Python 2 urllib2
).
Мое решение состояло в pip install certifi
для установки certifi
, который имеет:
... тщательно собранная коллекция корневых сертификатов для проверки достоверности SSL-сертификатов при проверке подлинности хостов TLS.
Затем в моем коде, где раньше я был:
import urllib.request as urlrq
resp = urlrq.urlopen('https://foo.com/bar/baz.html')
Я пересмотрел его, чтобы:
import urllib.request as urlrq
import certifi
resp = urlrq.urlopen('https://foo.com/bar/baz.html', cafile=certifi.where())
Если я правильно прочитал urllib2.urlopen
documentation, он также имеет аргумент cafile
. Таким образом, urllib2.urlopen([...], certifi.where())
может работать и для Python 2.7.
Ответ 8
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
Взято отсюда https://gist.github.com/michaelrice/a6794a017e349fc65d01
Ответ 9
Как я написал в комментарии, эта проблема, вероятно, связана с этим SO-ответом.
Короче: существует несколько способов проверки сертификата. Проверка, используемая OpenSSL, несовместима с доверенными корневыми сертификатами, которые у вас есть в вашей системе. OpenSSL используется Python.
Вы можете попытаться получить отсутствующий сертификат для Verisign Class 3 Public Primary Certification Authority, а затем использовать параметр cafile
в соответствии с Документация по Python:
urllib2.urlopen(req, cafile="verisign.pem")
Ответ 10
Для Python 3.4 + на Centos 6/7, Fedora, просто установите доверенный CA следующим образом:
- Скопируйте CA.crt в
/etc/pki/ca-trust/source/anchors/
-
update-ca-trust force-enable
-
update-ca-trust extract
Ответ 11
Я держу голову в полупотом, так как у меня была такая же проблема, за исключением того, что в моем случае URL-адрес, который я ударил, был действительным, сертификат был действительным. То, что было недействительным, было моим подключением к сети. Мне не удалось добавить данные прокси в браузер (в этом случае IE). Это остановило процесс проверки правильно.
Добавлено в подробности прокси, и мой python был тогда очень счастлив.
Ответ 12
Python 2.7.12 (по умолчанию, 29 июля 2016, 15:26:22) исправил указанную проблему. Эта информация может помочь кому-то еще.
Ответ 13
Мне нужно добавить еще один ответ, потому что, как и Крейг Гленни, я отправился в дикую погоню за гусями из-за многих сообщений, ссылающихся на эту проблему через Интернет.
Я использую MacPorts, и изначально я думал, что проблема с Python была на самом деле проблемой MacPorts: она не устанавливает корневой сертификат с его установкой openssl. Решение находится в port install curl-ca-bundle
, как указано в этом сообщении в блоге.
Ответ 14
Как и вы, я использую python 2.7 на моем старом iMac (OS X 10.6.8), я тоже встретил эту проблему, используя urllib2.urlopen:
urlopen error [SSL: CERTIFICATE_VERIFY_FAILED]
Мои программы работали нормально без проблем с сертификатами SSL и с удовольствием (после загрузки программ), они разбились с этой ошибкой SSL.
Проблема заключалась в использовании версии python:
Глава, называемая Certificate verification and OpenSSL [CHANGED for Python 2.7.9]
, в /Applications/Python 2.7/ReadMe.rtf
, объясняет проблему со многими деталями.
Итак, проверьте, загрузите и установите в свою PATH правильную версию python.
Ответ 15
Я удивлен, что вся эта инструкция не решила мою проблему. Тем не менее, диагностика правильная (BTW, я использую Mac и Python3.6.1). Итак, суммируем правильную часть:
- На Mac Apple отбрасывает OpenSSL
- Теперь Python использует собственный набор CA Root Certificate
- Двоичная установка Python предоставила script для установки корневого сертификата CA Python ( "/Applications/Python 3.6/Install Certificates.command" )
- Подробнее см. "/Applications/Python 3.6/ReadMe.rtf"
Для меня script не работает, и все эти установки certifi и openssl также не удалось исправить. Может быть, потому, что у меня есть несколько установок python 2 и 3, а также много virtualenv. В конце, мне нужно исправить это вручную.
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
Если это еще не удастся вам. Затем снова установите OpenSSL.
port install openssl
Ответ 16
Python 2.7 на Amazon EC2 с centOS 7
Мне пришлось установить переменную env SSL_CERT_DIR
чтобы указать на мой ca-bundle
который был расположен в /etc/ssl/certs/ca-bundle.crt
Ответ 17
Try
pip install --trusted-host pypi.python.org packagename
Это сработало для меня.
Ответ 18
Взгляните на
/Приложения/Python 3.6/Install Certificates.command
Вы также можете перейти к разделу "Приложения и нажмите" Certificates.command "
Ответ 19
Если вы на vCenter 6, вместо этого добавьте сертификат vmware сертификата vCenter vCenter в список ОС доверенных ЦС. Чтобы загрузить ваш сертификат, выполните следующие действия
- Откройте веб-браузер.
- Перейдите в https://
- В нижнем правом углу щелкните ссылку "Загрузить доверенный корневой CA"
В Fedora
- разархивируйте и измените расширение с .0 на .cer
- Скопируйте его в /etc/pki/ca -trust/source/anchors/
- запустите команду update-ca-trust.
Ссылки:
Ответ 20
шаги установки для nltk (у меня был установлен python3 (3.6.2) уже в MAC OS X
sudo easy_install pip
Использовать игнорировать установленную опцию, чтобы игнорировать удаление предыдущей версии из шести, иначе она выдает сообщение об ошибке при удалении и не переходит вперед вперед
sudo pip3 install -U nltk --ignore-installed six
Проверьте установку pip и python, используйте версии "3"
which python python2 python3
which pip pip2 pip3
Проверьте, установлен ли NLTK
python3
import nltk
nltk.__path__
['/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/nltk']
Установите сертификат SSL перед установкой книги примеров, иначе мы получим сертификат при установке примеров
/Applications/Python\ 3.6/Install\ Certificates.command
python3 -m nltk.downloader book
Это успешно завершило установку nltk и nltk_ata для примеров книг
Ответ 21
Установка PyOpenSSL
с помощью pip
работала для меня (без преобразования в PEM):
pip install PyOpenSSL
Ответ 22
Я решил эту проблему, закрыв Fiddler (прокси-сервер отладки HTTP), проверьте, включен ли прокси-сервер и повторите попытку.
Ответ 23
В python 2.7 добавление доверенных корневых данных CA в конце в файле C:\Python27\lib\site-packages\certifi\cacert.pem помогло
после этого я запустил (используя права администратора) pip install --trusted-host pypi.python.org --trusted-host pypi.org --trusted-host files.pythonhosted.org packageName
Ответ 24
Для тех, кто использует mechanize
который сталкивается с этим вопросом, вот как вы можете применить тот же метод к экземпляру браузера Mechanize:
br = mechanize.Browser()
context = ssl._create_unverified_context()
br.set_ca_data(context=context)
Ответ 25
Установка certifi на Mac решила мою проблему:
pip install certifi
Ответ 26
Я нашел это здесь
Я нашел это решение, вставьте этот код в начало вашего исходного файла:
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
Этот код отменяет проверку, поэтому сертификация ssl не проверяется.
Ответ 27
Для Linux Python3.6 это сработало для меня.
из командной строки установите pyopenssl и certifi
sudo pip3 install -U pyopenssl
sudo pip3 install certifi
и в моем скрипте на python3 добавлено verify = '/usr/lib/python3.6/site-packages/certifi/cacert.pem', например так:
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')
Ответ 28
Решение для Анаконды
Моя установка - Anaconda Python 3.7 на MacOS с прокси. Пути разные.
- Вот как вы получаете правильный путь сертификатов:
import ssl
ssl.get_default_verify_paths()
который в моей системе производится
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')
Как только вы узнаете, куда отправляется сертификат, вы соединяете сертификат, используемый прокси, в конец этого файла.
Я уже настроил conda для работы с моим прокси, запустив:
conda config --set ssl_verify <pathToYourFile>.crt
Если вы не помните, где находится ваш сертификат, вы можете найти его в ~/.condarc
:
ssl_verify: <pathToYourFile>.crt
Теперь конкатенируйте этот файл до конца /miniconda3/ssl/cert.pem
и запросы должны работать, и, в частности, должны работать sklearn.datasets
и подобные инструменты.
Дальнейшие предостережения
Другие решения не работали, потому что установка Anaconda немного отличается:
-
Путь Applications/Python\ 3.X
просто не существует.
-
Путь, предоставленный командами ниже, является НЕПРАВИЛЬНЫМ путем
from requests.utils import DEFAULT_CA_BUNDLE_PATH
DEFAULT_CA_BUNDLE_PATH
Ответ 29
В моем случае я получал эту ошибку, потому что requests
и версии urllib3
были несовместимы, приводя к следующей ошибке во время установки:
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
сделал свое дело.
Ответ 30
Еще одно решение Анаконды. Я получал CERTIFICATE_VERIFY_FAILED в моей среде Python 2.7 на macOS. Оказывается, конда пути были плохими:
базовая (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 окружение (пути не существовали!):
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')
Исправление:
cd /usr/local/anaconda3/envs/py27/
mkdir ssl
cd ssl
ln -s ../../../ssl/cert.pem