2012-11-22 41 views
10

Tôi đã sử dụng mô-đun cơ khí một trong khi trước đây, và bây giờ cố gắng sử dụng mô-đun yêu cầu.
(Python mechanize doesn't work when HTTPS and Proxy Authentication required)Làm thế nào để vượt qua proxy-xác thực (yêu cầu tiêu hóa auth) bằng cách sử dụng mô-đun yêu cầu python

Tôi phải truy cập proxy-server khi truy cập Internet.
Proxy-server yêu cầu xác thực. Tôi đã viết các mã sau đây.

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) 

Các mã ở trên hoạt động tốt khi máy chủ proxy yêu cầu xác thực cơ bản.
Bây giờ tôi muốn biết mình phải làm gì khi proxy-server yêu cầu xác thực thông báo.
HTTPProxyAuth có vẻ không hiệu quả trong việc xác thực thông báo (r.status_code trả về 407).

Trả lời

7

tôi đã viết các lớp có thể được sử dụng trong xác thực proxy (dựa trên tiêu hóa auth).
Tôi đã mượn gần như tất cả các mã từ 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 

Cách sử dụng:

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

Tôi gặp lỗi: đối tượng 'HTTPProxyDigestAuth' không có thuộc tính 'last_nonce'. Khi tôi thử và sử dụng lớp học của bạn. Tôi sẽ xem xét nó. – MattClimbs

+3

Không cần triển khai ngay bây giờ, 'yêu cầu' hiện đã được hỗ trợ cho proxy, ví dụ: 'proxy = {'https': 'https: // người dùng: mật khẩu @ ip: port'}; r = requests.get ('https: // url', proxy = proxies) 'xem http://docs.python-requests.org/en/latest/user/advanced/ – BurnsBA

+0

@BurnsBA @MattClimbs @yutaka tôi có thể xác nhận rằng việc sử dụng các yêu cầu trong Python 3 với https và 'user: password @ ip: port' hoạt động tốt. – jamescampbell

0

Bạn có thể sử dụng tiêu hóa xác thực bằng cách sử dụng requests.auth.HTTPDigestAuth thay vì requests.auth.HTTPProxyAuth

+0

Tôi muốn chuyển xác thực proxy (dựa trên xác thực thông báo). Đó là khác với auth tiêu hóa thông thường. Vì vậy, tôi cần mở rộng HTTPDigestAuth (xem bên dưới). – 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

Không cần phải thực hiện của riêng bạn!

Bây giờ yêu cầu đã được xây dựng trong hỗ trợ cho các proxy:

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

tham khảo thêm các docs

Đây là câu trả lời từ @BurnsBA đã cứu cuộc đời tôi.

Lưu ý: phải sử dụng ip của máy chủ proxy chứ không phải tên của máy chủ proxy!

Các vấn đề liên quan