Как прокси-аутентификация (требуется дайджест-аут) с помощью модуля запросов python

Я использовал модуль Mechanize некоторое время назад и теперь пытаюсь использовать модуль Requests.
(Механизм Python не работает, если требуется проверка подлинности HTTPS и прокси-сервера)

Мне нужно пройти через прокси-сервер, когда я получаю доступ к Интернету.
Прокси-сервер требует аутентификации. Я написал следующие коды.

import requests
from requests.auth import HTTPProxyAuth

proxies = {"http":"192.168.20.130:8080"}
auth = HTTPProxyAuth("username", "password")

r = requests.get("http://www.google.co.jp/", proxies=proxies, auth=auth)

Вышеприведенные коды хорошо работают, когда прокси-сервер требует базовой проверки подлинности.
Теперь я хочу знать, что мне нужно делать, когда для прокси-сервера требуется аутентификация дайджеста.
HTTPProxyAuth, похоже, не эффективен в аутентификации дайджеста (r.status_code возвращает 407).

Ответ 1

Я написал класс, который можно использовать в прокси-аутентификации (на основе дайджеста auth).
Я заимствовал почти все коды из request.auth.HTTPDigestAuth.

import requests
import requests.auth

class HTTPProxyDigestAuth(requests.auth.HTTPDigestAuth):
    def handle_407(self, r):
        """Takes the given response and tries digest-auth, if needed."""

        num_407_calls = r.request.hooks['response'].count(self.handle_407)

        s_auth = r.headers.get('Proxy-authenticate', '')

        if 'digest' in s_auth.lower() and num_407_calls < 2:

            self.chal = requests.auth.parse_dict_header(s_auth.replace('Digest ', ''))

            # Consume content and release the original connection
            # to allow our new request to reuse the same one.
            r.content
            r.raw.release_conn()

            r.request.headers['Authorization'] = self.build_digest_header(r.request.method, r.request.url)
            r.request.send(anyway=True)
            _r = r.request.response
            _r.history.append(r)

            return _r

        return r

    def __call__(self, r):
        if self.last_nonce:
            r.headers['Proxy-Authorization'] = self.build_digest_header(r.method, r.url)
        r.register_hook('response', self.handle_407)
        return r

Использование:

proxies = {
    "http" :"192.168.20.130:8080",
    "https":"192.168.20.130:8080",
}
auth = HTTPProxyDigestAuth("username", "password")

# HTTP
r = requests.get("http://www.google.co.jp/", proxies=proxies, auth=auth)
r.status_code # 200 OK

# HTTPS
r = requests.get("https://www.google.co.jp/", proxies=proxies, auth=auth)
r.status_code # 200 OK

Ответ 2

Не нужно реализовывать свой собственный! (в большинстве случаев)

Requests имеет встроенную поддержку прокси для базовой аутентификации:

proxies = { 'https' : 'https://user:[email protected]:port' } 
r = requests.get('https://url', proxies=proxies) 

см. больше в документации

. Или, если вам нужна дайджест-аутентификация, используйте:

from requests.auth import HTTPDigestAuth

proxies = { 'https' : 'https://proxyip:port' } 
requests.get('https://url', auth=HTTPDigestAuth('user', 'password'), proxies=proxies)

Примечание: необходимо использовать ip прокси-сервера, а не его имя!

Ответ 4

import requests
import os


# in my case I had to add my local domain
proxies = {
  'http': 'proxy.myagency.com:8080',
  'https': '[email protected]:[email protected]:8080',
}


r=requests.get('https://api.github.com/events', proxies=proxies)
print(r.text)

Ответ 5

Вы можете использовать аутентификацию дайджеста, используя requests.auth.HTTPDigestAuth вместо requests.auth.HTTPProxyAuth