首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Python urllib2 ProxyHandler 407 認證失敗:正確的代理驗證寫法

     編輯:程式設計綜合問答

錯誤原因

直接在 Proxy URL 嵌入帳密 https://user:pass@proxy:port 並傳給 `ProxyHandler`,**Python 2.7 的 `urllib2` 不支援此語法**,導致 407 Proxy Authentication Required。

正確做法:使用 HTTPPasswordMgrWithDefaultRealm + ProxyBasicAuthHandler

import urllib2

def build_proxy_opener(proxy_info):
    # proxy_info = {'user': 'xxx', 'password': 'xxx', 'server': 'proxy.example.com:8080'}
    password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
    password_mgr.add_password(None, proxy_info['server'], proxy_info['user'], proxy_info['password'])
    
    proxy_handler = urllib2.ProxyHandler({'http': proxy_info['server']})
    auth_handler = urllib2.ProxyBasicAuthHandler(password_mgr)
    
    opener = urllib2.build_opener(proxy_handler, auth_handler)
    return opener

proxy_info = {'user': 'myuser', 'password': 'mypass', 'server': 'proxy.corp.com:8080'}
opener = build_proxy_opener(proxy_info)
urllib2.install_opener(opener)

response = urllib2.urlopen('https://httpbin.org/ip')
print(response.read())

關鍵點解析

  1. HTTPPasswordMgrWithDefaultRealm 管理認證憑證,`None` 表示適用於所有 Realm。
  2. add_password 的第 2 參數為 **代理伺服器 URI** (不含 scheme),而非目標網站 URI。
  3. ProxyBasicAuthHandler 專門處理 407 回應,自動插入 `Proxy-Authorization` 標頭。
  4. build_opener 依序傳入 `ProxyHandler` (建立隧道) 與 `ProxyBasicAuthHandler` (掛載認證)。

Python 3 版本 (urllib.request)

import urllib.request

password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
password_mgr.add_password(None, 'proxy.corp.com:8080', 'myuser', 'mypass')

proxy_handler = urllib.request.ProxyHandler({'http': 'proxy.corp.com:8080'})
auth_handler = urllib.request.ProxyBasicAuthHandler(password_mgr)

opener = urllib.request.build_opener(proxy_handler, auth_handler)
urllib.request.install_opener(opener)

with urllib.request.urlopen('https://httpbin.org/ip') as f:
    print(f.read().decode())

進階:HTTPS 代理與 CONNECT 隧道

  • 若代理需處理 HTTPS 目標,確保代理支援 CONNECT 方法。
  • Python 2.7 `urllib2` 對 HTTPS 代理支援有限,建議改用 requests 庫:
    import requests
    proxies = {'http': 'https://user:pass@proxy:8080', 'https': 'https://user:pass@proxy:8080'}
    requests.get('https://api.example.com', proxies=proxies) # requests 完美支援 URL 嵌入帳密
    

結論:urllib2 必須分離 ProxyHandler 與 ProxyBasicAuthHandler;現代專案強烈建議直接使用 requests。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved