2016-03-18 162 views
4

我想通過使用urllib2.ProxyHandler測試代理連接。但是,可能有一些情況是我要請求HTTPS網站(例如:https://www.whatismyip.com/Python - 如何使用(Urllib2 + SSL)通過HTTP代理處理HTTPS請求

如果請求HTTPS站點,Urllib2.urlopen()將引發錯誤。所以我嘗試使用一個輔助函數來重寫URLOPEN方法。

這裏是輔助功能:

def urlopen(url, timeout): 
    if hasattr(ssl, 'SSLContext'): 
     SslContext = ssl.create_default_context() 
     SslContext.check_hostname = False 
     SslContext.verify_mode = ssl.CERT_NONE 
     return urllib2.urlopen(url, timeout=timeout, context=SslContext) 
    else: 
     return urllib2.urlopen(url, timeout=timeout) 

這個輔助功能基於answer

然後我用:

urllib2.install_opener(
    urllib2.build_opener(
     urllib2.ProxyHandler({'http': '127.0.0.1:8080'}) 
    ) 
) 

設置HTTP代理的urllib.opener。

理想情況下,它應該在我通過使用urlopen('http://whatismyip.com', 30)請求網站時工作,並且它應該通過http代理傳遞所有流量。

但是,即使它是HTTP站點,urlopen()也會一直屬於if hasattr(ssl, 'SSLContext')。另外,HTTPS站點也不使用HTTP代理。這導致HTTP代理變得無效,並且所有流量都通過未經處理的網絡

我也試過這個answer將HTTP更改爲HTTPS urllib2.ProxyHandler({'https': '127.0.0.1:8080'}),但它仍然不起作用。

我的代理正在工作。如果我使用urllib2.urlopen()而不是重寫版本urlopen(),它適用於HTTP站點。

但是,如果需要在HTTPS ONLY站點上使用urlopen,我確實需要考慮su客。

如何做到這一點?

感謝

UPDATE1:我不能與Python 2.7.11得到這個工作,一些服務器使用Python 2.7.5正常工作的。我認爲這是python版本問題。

Urllib2不會通過HTTPS代理,因此所有HTTPS網址都無法使用代理。

回答

2

我個人會建議使用諸如python-requests之類的東西,因爲它可以緩解很多直接使用urllib2設置代理的問題。當使用requests與代理,你必須做的:(從他們documentation

import requests 

proxies = { 
    'http': 'http://10.10.1.10:3128', 
    'https': 'http://10.10.1.10:1080', 
} 

requests.get('http://example.org', proxies=proxies) 

和禁用SSL證書驗證是通過verify=False上述requests.get命令一樣簡單。但是,這應該謹慎使用,並且應該解決SSL證書驗證的實際問題。

+0

我試過了,但requests.get只會返回狀態碼,我需要從網站上的某些內容(例如IP地址) – SharkIng

+0

@SharkIng您應該可以通過以下方式檢索內容:var = request.get( ...); print var.content'。 –

2

問題是,當你通過context參數urllib2.urlopen()然後創建的urllib2首戰itself,而不是using全局的,也就是當你調用urllib2.install_opener()時設置的一個。因此,您打算使用的ProxyHandler實例未被使用。
解決方案不是安裝opener,而是直接使用opener。構建開門紅時,必須同時通過ProxyHandler類的實例(設置http和https協議的代理)和HTTPSHandler類的實例(to set https context)。我爲此問題創建了https://bugs.python.org/issue29379

0

還有一個解決辦法是用ProxyHandler通過contextHTTPSHandler和該處理程序傳遞到build_opener在一起:

proxies = {'https': 'http://localhost:8080'} 
proxy = urllib2.ProxyHandler(proxies) 
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) 
handler = urllib2.HTTPSHandler(context=context) 
opener = urllib2.build_opener(proxy, handler) 
urllib2.install_opener(opener) 

現在,您可以查看您的代理所有的HTTPS請求/響應。