Ответ 1
urllib2 по умолчанию не проверяет сертификат сервера. Проверьте документацию.
Изменить: как указано в комментарии ниже, это больше не верно для более новых версий (похоже, как >= 2.7.9) Python. Обратитесь к ANSWER
Я хочу игнорировать certification validation
во время моего запроса на сервер с внутренней корпоративной ссылкой.
В библиотеке python requests
я бы сделал следующее:
r = requests.get(link, allow_redirects=False,verify=False)
Как мне сделать то же самое с библиотекой urllib2?
urllib2 по умолчанию не проверяет сертификат сервера. Проверьте документацию.
Изменить: как указано в комментарии ниже, это больше не верно для более новых версий (похоже, как >= 2.7.9) Python. Обратитесь к ANSWER
Тем временем urllib2, по-видимому, проверяет сертификаты сервера по умолчанию. Предупреждение которое было показано в прошлом исчезло для 2.7.9, и я в настоящее время столкнулись с этой проблемой в тестовой среде с самозаверяющим сертификатом (и Python 2.7.9).
Мое злое обходное решение (не делайте этого в процессе производства!):
import urllib2
import ssl
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
urllib2.urlopen("https://your-test-server.local", context=ctx)
В соответствии с документами сам вызов конструктора SSLContext также должен работать. Я этого не пробовал.
Самый простой способ:
питон 2
import urllib2, ssl
request = urllib2.Request('https://somedomain.co/')
response = urllib2.urlopen(request, context=ssl._create_unverified_context())
питон 3
from urllib.request import urlopen
import ssl
response = urlopen('https://somedomain.co', context=ssl._create_unverified_context())
Для тех, кто использует открыватель, вы можете добиться того же, что и на основе замечательного ответа Enno Gröper:
import urllib2, ssl
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
opener = urllib2.build_opener(urllib2.HTTPSHandler(context=ctx), your_first_handler, your_second_handler[...])
opener.addheaders = [('Referer', 'http://example.org/blah.html')]
content = opener.open("https://localhost/").read()
И затем используйте его как прежде.
Согласно build_opener и HTTPSHandler, HTTPSHandler добавляется, если модуль ssl
существует, здесь мы просто укажем наш собственный, а не стандартный.
Согласно сообщению @Enno Gröper, я пробовал конструктор SSLContext, и он хорошо работает на моей машине. код как показано ниже:
import ssl
ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
urllib2.urlopen("https://your-test-server.local", context=ctx)
если вам нужен открывалка, просто добавьте этот контекст, например:
opener = urllib2.build_opener(urllib2.HTTPSHandler(context=ctx))
ПРИМЕЧАНИЕ: все вышеперечисленное тестовое окружение - python 2.7.12. Я использую здесь PROTOCOL_SSLv23, поскольку doc говорит о том, что другой протокол также может работать, но зависит от вашего компьютера и удаленного сервера, пожалуйста, проверьте документ для подробностей.
Более явный пример, построенный на коде Дэмиена (вызывает тестовый ресурс http://httpbin.org/). Для python3. Обратите внимание, что если сервер перенаправляет на другой URL-адрес, uri
в add_password
должен содержать новый корневой URL (также можно передать список URL-адресов).
import ssl
import urllib.parse
import urllib.request
def get_resource(uri, user, passwd=False):
"""
Get the content of the SSL page.
"""
uri = 'https://httpbin.org/basic-auth/user/passwd'
user = 'user'
passwd = 'passwd'
context = ssl.create_default_context()
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
password_mgr.add_password(None, uri, user, passwd)
auth_handler = urllib.request.HTTPBasicAuthHandler(password_mgr)
opener = urllib.request.build_opener(auth_handler, urllib.request.HTTPSHandler(context=context))
urllib.request.install_opener(opener)
return urllib.request.urlopen(uri).read()