2012-11-22 31 views
10

का उपयोग कर प्रॉक्सी-प्रमाणीकरण (पाचन ऑथ की आवश्यकता है) को पास करने के लिए कैसे करें, मैं कुछ समय पहले मैकेनाइज मॉड्यूल का उपयोग कर रहा था, और अब अनुरोध मॉड्यूल का उपयोग करने का प्रयास करें।
(Python mechanize doesn't work when HTTPS and Proxy Authentication required)पाइथन अनुरोध मॉड्यूल

जब मैं इंटरनेट का उपयोग करता हूं तो मुझे प्रॉक्सी सर्वर से गुज़रना पड़ता है।
प्रॉक्सी-सर्वर प्रमाणीकरण की आवश्यकता है। मैंने निम्नलिखित कोड लिखे हैं।

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 देता है)।

उत्तर

7

की मैं कक्षा कि प्रॉक्सी प्रमाणीकरण में इस्तेमाल किया जा सकता लिखा द्वारा प्रमाणीकरण को पचाने का उपयोग कर सकते (प्रमाणन को पचाने के आधार पर)।
मैंने 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

मुझे त्रुटि मिलती है: 'HTTPProxyDigestAuth' ऑब्जेक्ट में कोई विशेषता 'last_nonce' नहीं है। जब मैं आपकी कक्षा का प्रयास करता हूं और उसका उपयोग करता हूं। मैं इस पर गौर करूंगा। – MattClimbs

+3

अब अपने आप को लागू करने की कोई आवश्यकता नहीं है, 'अनुरोध' अब प्रॉक्सी के लिए समर्थन में बनाया गया है, उदा। 'प्रॉक्सी = {'https': 'https: // उपयोगकर्ता: पासवर्ड @ आईपी: पोर्ट'}; आर = request.get ('https: // url', proxies = proxies) 'http://docs.python-requests.org/en/latest/user/advanced/ – BurnsBA

+0

@ बर्नस्बा @ मैटक्लिब्स @ यूटाका मैं देख सकता हूं पुष्टि करें कि https के साथ पायथन 3 में अनुरोधों का उपयोग और 'उपयोगकर्ता: पासवर्ड @ आईपी: पोर्ट' बहुत अच्छा काम करता है। – jamescampbell

0

आप requests.auth.HTTPDigestAuth उपयोग करने के बजाय requests.auth.HTTPProxyAuth

+0

मैं प्रॉक्सी ऑथ पास करना चाहता था (डाइजेस्ट ऑथ पर आधारित)। यह सामान्य पाचन लेखक से अलग है। तो मुझे HTTPDigestAuth (नीचे देखें) का विस्तार करने की आवश्यकता है। – yutaka

1

आपको लगता है कि अभी भी यहाँ अंत में से उन लोगों के लिए, वहाँ एक परियोजना के नाम से जाना करने के लिए अनुरोध-टूलबेल्ट इस प्रतीत होता है कि प्लस अन्य आम लेकिन अनुरोधों की कार्यक्षमता में बनाया नहीं।

https://toolbelt.readthedocs.org/en/latest/authentication.html#httpproxydigestauth

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

अपने स्वयं के लागू करने के लिए कोई ज़रूरत नहीं!

अब अनुरोध प्रॉक्सी के लिए समर्थन में बनाया गया है:

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

docs

पर और अधिक देखने यह है कि मेरी जान बचाई @BurnsBA से जवाब है।

नोट: प्रॉक्सी सर्वर का आईपी इसका नाम नहीं होना चाहिए!