10

J'utilisais le module Mechanize il y a quelques temps, et j'essaie maintenant d'utiliser le module Requêtes.
(Python mechanize doesn't work when HTTPS and Proxy Authentication required)Comment passer l'authentification proxy (requiert l'authentification digest) en utilisant le module de requêtes python

Je dois passer par un serveur proxy lorsque j'accède à Internet.
Le serveur proxy requiert une authentification. J'ai écrit les codes suivants.

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) 

Les codes ci-dessus fonctionnent bien lorsque le serveur proxy requiert une authentification de base.
Maintenant, je veux savoir ce que je dois faire quand le serveur proxy requiert une authentification Digest.
HTTPProxyAuth semble ne pas être efficace dans l'authentification Digest (r.status_code renvoie 407).

Répondre

7

J'ai écrit la classe qui peut être utilisé dans l'authentification proxy (basé sur la digestion auth).
J'ai emprunté presque tous les codes de requests.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 

Utilisation:

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

Je reçois l'erreur: L'objet 'HTTPProxyDigestAuth' n'a pas d'attribut 'last_nonce'. Quand j'essaye d'utiliser ta classe. Je vais regarder dedans. – MattClimbs

+3

Pas besoin d'implémenter le vôtre maintenant, 'requests' a maintenant intégré le support des proxies, par ex. 'proxies = {'https': 'https: // utilisateur: mot de passe @ ip: port'}; r = requests.get ('https: // url', proxies = proxies) 'voir http://docs.python-requests.org/en/latest/user/advanced/ – BurnsBA

+0

@BurnsBA @MattClimbs @yutaka Je peux confirmez que l'utilisation des requêtes en Python 3 avec https et le 'utilisateur: mot de passe @ ip: port' fonctionne très bien. – jamescampbell

0

Vous pouvez utiliser l'authentification digest à l'aide requests.auth.HTTPDigestAuth au lieu de requests.auth.HTTPProxyAuth

+0

Je voulais passer l'authentification proxy (basée sur l'authentification digest). C'est différent de l'authentification digest habituelle. J'ai donc besoin d'étendre HTTPDigestAuth (voir ci-dessous). – yutaka

0
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) 
1

Pas besoin de mettre en œuvre votre propre!

Maintenant demandes a un support intégré pour les procurations:

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

voir plus sur le docs

Ceci est la réponse de @BurnsBA qui a sauvé ma vie.

Note: doit utiliser ip du serveur proxy pas son nom!

Questions connexes