2012-11-22 13 views
10

kullanarak proxy kimlik doğrulaması nasıl geçilir (özet kimlik doğrulaması gerektirir) Bir süre önce Mechanize modülünü kullanıyordum ve şimdi İstekler modülünü kullanmaya çalışıyorum.
(Python mechanize doesn't work when HTTPS and Proxy Authentication required)Python istekleri modülü

Internet'e eriştiğimde proxy sunucudan geçmem gerekiyor.
Proxy sunucusu kimlik doğrulaması gerektirir. Aşağıdaki kodları yazdım.

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) 

Proxy sunucu temel kimlik doğrulaması gerektirdiğinde yukarıdaki kodlar iyi çalışır.
Şimdi, proxy sunucusunun özet kimlik doğrulaması gerektirdiğinde ne yapmam gerektiğini bilmek istiyorum.
HTTPProxyAuth, özet kimlik doğrulamasında etkili olmayacaktır (r.status_code, 407 döndürür).

cevap

7

I proxy kimlik kullanılabilecek sınıfı yazdım tarafından Özet kimlik doğrulaması kullanabilirsiniz (kimlik doğrulama sindirmek dayanarak).
Neredeyse tüm kodları requests.auth.HTTPDigestAuth adresinden ödünç aldım.

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 

Kullanımı: hala burada sona olanlar için

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

Hata alıyorum: 'HTTPProxyDigestAuth' nesnesinin 'last_nonce' özniteliği yok. Dersi kullanmaya çalıştığımda. Ben ona bakacağım. – MattClimbs

+3

Şimdi kendi isteğinizi uygulamanıza gerek yok, 'istekleri 'artık vekiller için destek oluşturmuştur, ör. proxy'ler = {'https': 'https: // kullanıcı: şifre @ ip: port'}; r = requests.get ('https: // url', proxy'ler = proxy'ler) bkz http://docs.python-requests.org/en/latest/user/advanced/ – BurnsBA

+0

@BurnsBA @MattClimbs @yutaka I can Python 3'teki isteklerin https ve "user: password @ ip: port" ile kullanılmasının harika olduğunu onaylayın. – jamescampbell

0

Sen requests.auth.HTTPDigestAuth kullanarak yerine requests.auth.HTTPProxyAuth

+0

Proxy yetkisini (sindirim durumuna göre) geçmek istedim. Bu her zamanki sindirim ağrısından farklıdır. Bu yüzden HTTPDigestAuth'ı genişletmem gerekiyordu (aşağıya bakın). – 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

Kendi uygulamak gerek yok!

Şimdi istekleri vekiller için destek inşa etti:

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

Bu hayatımı kurtardı @BurnsBA gelen cevaptır docs

daha görüyoruz.

Not: proxy sunucusunun ipini isminde değil kullanmalısınız!