Python – как обрабатывать HTTPS-запрос с помощью (Urllib2 + SSL), хотя HTTP-прокси

Я пытаюсь проверить прокси-соединение, используя urllib2.ProxyHandler. Однако, вероятно, есть некоторые ситуации, которые я собираюсь запросить на HTTPS-сайте (например: https://www.whatismyip.com/ )

Urllib2.urlopen () будет бросать ERROR, если запрашивает HTTPS-сайт. Поэтому я попытался использовать вспомогательную функцию для перезаписи метода URLOPEN.

Вот вспомогательная функция:

def urlopen(url, timeout): if hasattr(ssl, 'SSLContext'): SslContext = ssl.create_default_context() SslContext.check_hostname = False SslContext.verify_mode = ssl.CERT_NONE return urllib2.urlopen(url, timeout=timeout, context=SslContext) else: return urllib2.urlopen(url, timeout=timeout) 

Эта вспомогательная функция, основанная на ответе

Затем я использую:

 urllib2.install_opener( urllib2.build_opener( urllib2.ProxyHandler({'http': '127.0.0.1:8080'}) ) ) 

настроить http proxy для urllib.opener.

В идеале, он должен работать, когда я запрашиваю сайт с помощью urlopen('http://whatismyip.com', 30) и он должен передавать весь трафик через http proxy.

Однако urlopen() будет падать, if hasattr(ssl, 'SSLContext') все время, даже если это HTTP-сайт. Кроме того, сайт HTTPS также не использует HTTP-прокси. Это приведет к тому, что прокси-сервер HTTP станет недействительным, и весь трафик, проходящий через несвязанную сеть

Я также попробовал этот ответ для изменения HTTP в HTTPS urllib2.ProxyHandler({'https': '127.0.0.1:8080'}) но он все еще не работает.

Мой прокси работает. Если я использую urllib2.urlopen() вместо переписывающей версии urlopen() , он работает для сайта HTTP.

Но мне нужно рассмотреть вопрос о целесообразности использования urlopen на сайте HTTPS ONLY.

Как это сделать?

благодаря

UPDATE1: Я не могу получить эту работу с Python 2.7.11, а некоторые из серверов работают правильно с Python 2.7.5. Я понимаю, что это проблема с версией python.

Urllib2 не будет пропускать HTTPS-прокси, поэтому на весь HTTPS-адрес не будет прокси-сервер.

Проблема заключается в том, когда вы передаете context аргумент urllib2.urlopen() тогда urllib2 создает сам openener вместо использования глобального, который устанавливается, когда вы вызываете urllib2.install_opener() . В результате ваш экземпляр ProxyHandler который вы собираетесь использовать, не используется.
Решение заключается не в том, чтобы установить нож, а в непосредственное использование открывателя. При создании своего открывателя вам необходимо передать как экземпляр вашего класса ProxyHandler (установить прокси для протоколов http и https), так и экземпляр класса HTTPSHandler ( установить https-контекст ).

Я создал https://bugs.python.org/issue29379 для этой проблемы.

Я лично предложил бы использовать что-то вроде python-requests как это облегчит многие проблемы с настройкой прокси- urllib2 напрямую с помощью urllib2 . При использовании requests с прокси-сервером вам необходимо будет: (из их документации )

 import requests proxies = { 'http': 'http://10.10.1.10:3128', 'https': 'http://10.10.1.10:1080', } requests.get('http://example.org', proxies=proxies) 

И отключить проверку SSL-сертификата так же просто, как передать verify=False команду requests.get выше. Однако это следует использовать экономно, и фактическая проблема с проверкой сертификата SSL должна быть разрешена.

Еще одно решение – передать context в HTTPSHandler и передать этот обработчик в build_opener вместе с ProxyHandler :

 proxies = {'https': 'http://localhost:8080'} proxy = urllib2.ProxyHandler(proxies) context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) handler = urllib2.HTTPSHandler(context=context) opener = urllib2.build_opener(proxy, handler) urllib2.install_opener(opener) 

Теперь вы можете просмотреть все ваши HTTPS-запросы / ответы в своем прокси-сервере.