注: urllib2 模塊在Python 3 中被拆分紅了 urllib.request 和 urllib.error . 當你將你的代碼轉換到 Python 3 時, 2to3 工具可以自動地幫助你調整導入的模塊html
urllib2 模塊定義了在複雜的世界中幫助你打開 URL (大部分是 HTTP )的函數和類 - 包括基本和摘要式認證,重定向,cookie和更多的一些功能.python
打開參數 url 中的URL, url 參數能夠是字符串類型或者 Request 對象.算法
警告: HTTPS 請求不會驗證任何服務器的證書.sql
data 參數多是指定發送到服務器的額外數據的字符串,若是沒有這樣的數據的話它將是 None
.目前只有 HTTP 的請求會使用 data 參數;當提供 data 參數時, HTTP 請求會將 GET 請求替換爲 POST 請求. data 參數應當是標準的 application/x-www-form-urlencoded 格式的緩衝. urllib2.urlencode() 函數接受一個映射或者包含二元元組的序列做爲參數並返回一個符合格式的字符串. urllib2 模塊發送包含了 Connection:close
頭的 HTTP/1.1 請求.數據庫
可選參數 timeout 指定了相似於鏈接嘗試的阻塞操做超時的秒數(若是沒有指定的話,將使用全局的超時設置).這個參數僅對 HTTP , HTTPS 和 FTP 鏈接有效.編程
這個函數返回一個添加了如下三個方法的類文件對象:vim
geturl() - 返回檢索到的資源的URL,一般用於肯定是否跟隨了一個重定向瀏覽器
info() - 以一個 mlmetools.Message 實例的形式返回頁面的元信息,例如頭緩存
getcode() - 返回 HTTP 響應的狀態碼bash
觸發 URLError 的錯誤.
注意若是沒有處理器處理請求(儘管默認狀況下安裝全局的 OpenerDirector 使用 UnknownHandler 來確保這種狀況永遠不會發生),函數可能返回None
.
另外,若是檢測到代理設置(例如,當一個 *_proxy
環境變量被設置時,好比 http_proxy ), ProxyHandler 會被默認安裝確保處理請求使之經過代理.
安裝一個 OpenerDirector 實例做爲默認的全局 opener.安裝一個 opener 僅在你但願 urlopen() 函數使用它時纔是必須的;不然,簡單的調用 OpenDirector.open() 來代替 urlopen() .代碼不會檢查一個真正的 OpenerDirector , 而且任何類相應的接口都將工做.
返回一個鏈接了按順序給出的處理器的 Openerdirector 實例. handlers 能夠是 BaseHandler 的任何實例,或者是 BaseHandler 的子類(在這種狀況下它必須可以調用沒有任何參數的結構).如下類的實例必須在 handler 以前,除非 handlers 包含了它們的實例或者他們的子類的實例: ProxyHandler (若是代理設置被檢測到), UnknownHandler , HTTPHandler , HTTPDefaultErrorHandler , HTTPRedirectHandler , FTPHandler , FileHandler , HTTPErrorProcessor.
若是安裝的 Python 支持 SSL (例如 ssl 模塊可以被導入), HTTPHandler 也將被添加.
從 Python 2.3 開始,一個 BaseHandler 的子類也有可能改變它的 handler_order 屬性以修改它在處理器列表中的位置.
如下異常會在會在合適的狀況下觸發:
處理器觸發這個錯誤(或者衍生的錯誤)當它們運行時出了一個問題.它是 IOError 的子類.
這個錯誤返回的緣由多是一個信息字符串或者另一個異常實例(對遠程 URL 的 socket.error,對本地 URL 的 OSError).
儘管是一個異常( URLError 的一個子類),一個 HTTPError 也能夠做爲一個函數無異常的類文件返回值(與 urlopen 返回的東西同樣).這在處理特殊的 HTTP 錯誤時會很是有用,例如身份驗證的請求
一個於 RFC 2616 標準中定義的 HTTP 狀態碼.這個數字值是 BaseHTTPServer.BaseHTTPRequestHandler.responses 狀態碼字典中對應的一個值
這個錯誤返回的緣由多是一個信息字符串或者另一個異常實例
這個類是對 URL 請求的抽象.
url 應該是一個包含有效 URL 的字符串.
data 參數多是指定發送到服務器的額外數據的字符串,若是沒有這樣的數據的話它將是 None
.目前只有 HTTP 的請求會使用 data 參數;當提供 data 參數時, HTTP 請求會將 GET 請求替換爲 POST 請求. data 參數應當是標準的 application/x-www-form-urlencoded 格式的緩衝. urllib2.urlencode() 函數接受一個映射或者包含二元元組的序列做爲參數並返回一個符合格式的字符串.
headers 應當是一個字典,能夠看做是將每一個鍵和值看成參數調用 add_header() 函數. 這常常用來修改瀏覽器用來聲明自身的 User-Agent
頭 - 一些常見HTTP服務器只容許請求來自瀏覽器而不是腳本.例如,火狐瀏覽器將聲明本身爲 "Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11"
,同時 urllib2 的默認用戶代理字符串爲 "Python-urllib/2.6"
(在 Python 2.6 中)
最後兩個參數僅對正確地處理第三方 HTTP cookies 感興趣:
origin_req_host 應當是在 RFC 2965 中定義的起源事務的請求主機.它默認爲 cookielib.request_host(self)
.這是被用戶發起的主機名或 IP 地址.例如,若是請求是從一份 HTML 文檔中得到一張圖像,參數就應該是得到包含圖像的頁面的請求的請求主機.
unverfiable 應當聲明請求是不是不被驗證的,這在 RFC 2965 中被定義.它默認爲 False
.一個不被驗證的請求是用戶未選擇容許選項的 URL.例如,若是請求是從一份 HTML 文檔中得到一張圖像,而且用戶未選擇選項容許自動地抓取圖像,參數便應該爲 True
.
這個類經過鏈接起來的 BasHandler 打開 URL ,它管理這些處理器鏈而且能從錯誤中恢復.
這是全部註冊過的處理器的基類 -僅僅負責處理註冊的簡單結構.
這是一個爲 HTTP 錯誤響應定義的默認處理器;全部的響應都轉換成了 HTTPError 異常.
這是一個爲處理重定向的類.
這是一個爲處理 HTTP Cookie的類.
是請求經過代理.若是 proxies 參數被提供,它必定是一個協議名稱映射到代理地址的字典.默認從環境變量 **_proxy** 讀取到代理列表.若是沒有設置代理環境變量,在 Windows 環境中,那麼從註冊表的網絡設置部分讀取代理設置,在Mac OS X環境中,從OS X系統配置框架檢索代理信息.
若要關閉自動代理檢測填入一個空字典便可.
保持一個 (realm, uri) -> (user, password) 映射數據庫
保持一個 (realm, uri) -> (user, password) 映射數據庫. 一個爲None
的域被認爲是匹配全部的域,它將被搜索若是沒有其餘的域匹配的話.
這是一個幫助 HTTP 驗證的混入類,包括遠程主機驗證和代理驗證. password_mgr 參數若是被提供,應當是與 HTTPPasswordMgr 相兼容的;涉及到 HTTPPasswordMgr 對象部分的接口信息必須被支持.
「混入類被定義爲‘一種被設計爲經過繼承與其餘類結合的類’,它給其餘類提供可選擇的接口或功能。從實現上講,混入類要求多繼承;混入類一般是抽象類,不 能實例化。混入類的做用在於:它不只能夠提升功能的重用性,減小代碼冗餘;並且還可使相關的‘行爲’集中在一個類中,而不是分佈到多個類中,減小了避免 所謂的‘代碼分散’和‘代碼交織’問題,提升可維護性。」
處理遠程主機的身份驗證. password_mgr 參數若是被提供,應當是與 HTTPPasswordMgr 相兼容的; refer to section HTTPPasswordMgr Objects for information on the interface that must be supported.
處理代理的驗證. password_mgr 參數若是被提供,應當是與 HTTPPasswordMgr 相兼容的;涉及到 HTTPPasswordMgr 對象部分的接口信息必須被支持.
這是一個幫助 HTTP 驗證的混入類,包括遠程主機驗證和代理驗證. password_mgr 參數若是被提供,應當是與 HTTPPasswordMgr 相兼容的;涉及到 HTTPPasswordMgr 對象部分的接口信息必須被支持.
處理遠程主機的身份驗證. password_mgr 參數若是被提供,應當是與 HTTPPasswordMgr 相兼容的;涉及到 HTTPPasswordMgr 對象部分的接口信息必須被支持.
處理代理的驗證. password_mgr 參數若是被提供,應當是與 HTTPPasswordMgr 相兼容的; 涉及到 HTTPPasswordMgr 對象部分的接口信息必須被支持.
一個用於處理 HTTP 地址打開的類.
一個用於處理 HTTPS 地址打開的類.
打開本地文件.
打開 FTP 地址.
打開 FTP 地址,保持打開的 FTP 鏈接緩存以減小延遲.
一個用於處理未知地址的全面的類.
處理 HTTP 響應錯誤.
如下方法描述了 Request 對象的公共接口,所以全部接口必須在子類中被覆蓋.
- Request.add_data(data)
將請求數據設置爲 data .除了 HTTP 處理器,其餘處理器會忽略這個函數 - 而且參數應當是一個字節字符串,而且請求會由 GET
變爲 POST
.
- Request.get_method()
返回一個指示 HTTP 請求方法的字符串.這僅對 HTTP 請求有意義,而且通常老是返回 GET
或者 POST
.
- Request.has_data()
檢查是否實例含有 POST
數據.
- Request.get_data()
返回實例的 POST
數據.
- Request.add_header(key, val)
添加額外的一個請求頭,頭一般會被除 HTTP 處理器以外的全部處理器在被添加進頭列表發送至服務器的地方忽略掉.注意,不能有兩個相同名稱的頭,而且後添加的頭會覆蓋掉以前有衝突的頭.目前來說,這並非 HTTP 功能的缺陷,由於全部有意義的頭在使用超過兩次時會有一種方法(header-specific)只使用一個頭得到相同的功能.
- Request.add_unredirected_header(key, header)
添加一個不會被添加到重定向後的請求的頭.
- Request.has_header(header)
檢查是否實例擁有參數中的頭(檢查普通的頭和不被重定向的頭).
- Request.get_full_url()
返回在構造函數中傳遞的 URL .
- Request.get_type()
返回 URL 的類型 - 也被稱爲 scheme
(注:應該是協議的意思,待測試)
- Request.get_host()
返回創建鏈接的主機.
- Request.get_selector()
返回選擇器 - URL 中發送到服務器中的部分.
- Request.get_header(header_name, default=None)
返回指定頭的值.若是這個頭沒有出現將返回默認值.
- Request.header_items()
返回一個包含全部請求頭的元組(header_name, header_value)列表
- Request.set_proxy(host, type)
鏈接代理服務器以準備請求. host 和 type 將代替這些實例,而且實例的選擇器將會變成給予構造函數的原始 URL .
- Request.get_origin_req_host()
返回起源事務的請求主機,這是在 RFC 2965中被定義的. 能夠查看 Request 構造函數的文檔.
- Request.is_unverifiable()
檢查是否請求時不被驗證的,這是在 RFC 2965中被定義的.能夠查看 Request 構造函數的文檔.
OpenerDirector 對象有如下方法:
- OpenerDirector.add_handler(handler)
handler 應當是一個 BaseHandler 實例.如下方法會被尋找並被添加到可能的鏈中(注意 HTTP 錯誤是特殊的狀況).
- `*protocol_open*` - 信號處理程序知道如何打開 `*protocol_open*` 地址. - `*http_error_type*` - 信號處理程序知道如何處理 HTTP 錯誤碼類型. - `*protocol_error*` - 信號處理程序知道如何處理來自於協議( non-`http` )的錯誤. - `*protocol_request*` - 信號處理程序知道如何預處理協議請求. - `*protocol_response*` - 信號處理程序知道如何預處理協議響應. - OpenerDirector.open(url[, data][, timeout])
打開提供的 url (多是一個請求對象或者字符串), data 能夠忽略.給予參數,返回值和觸發的異常是和 urlopen() (簡單的調用通常的全局 OpenerDirector 對象中的 open() 方法)同樣的.可選參數 timeout 指定了相似於鏈接嘗試的阻塞操做超時的秒數(若是沒有指定的話,將使用全局的超時設置).這個參數僅對 HTTP , HTTPS 和 FTP 鏈接有效.
- OpenerDirector.error(proto[, arg[, ...]])
處理一個提供的協議的錯誤.這將爲提供的帶有參數(指明協議詳情)的協議調用以註冊的錯誤處理器. HTTP 是一個特殊的例子,由於它使用 HTTP 響應碼來決定特定的錯誤處理器;這裏指的是處理器類中的 **http_error_*()** 方法.
返回值和觸發的異常是和 urlopen() 同樣的.
OpenerDirector 對象打開地址分爲三步:
每一個階段的方法在哪裏以何種順序被調用取決於處理器實例的順序.
1. 每一個帶有命名相似於 *`protocol_request`* 方法的處理器都會調用這個方法來預處理請求. 2. 每一個帶有命名相似於 *`protocol_open`* 方法的處理器都會調用這個方法來處理請求.當一個非 **None** (例如一個響應)值被返回或者出發一個異常時(一般是 **URLError** ),這個階段將會結束.異常能夠傳播.
實際上,以上算法首先嚐試過 default_open() 方法.若是全部的方法返回 None,算法會重複命名相似於 protocol_open
的方法.若是以上全部的方法都返回 None,算法將會重複命名爲 unknown_open() 的方法.
注意,這些方法的實現可能涉及到調用父類 OpenerDirector 實例的 open() 和error() 方法。
3. 每一個帶有命名相似於 *`protocol_response`* 方法的處理器都會調用這個方法來後處理響應.
BaseHandler 對象提供了一些直接有效的方法,另一些方法則是被派生類使用的.這些都是用於直接使用:
- BaseHandler.add_parent(director)
Add a director as parent.
- BaseHandler.close()
Remove any parents.
如下屬性和方法僅被 BaseHandler 的派生類使用.
注意: 子類對 protocol_request
和 protocol_response()
方法的命名約定爲 *Processor
;其它全部的命名爲 *Handler
.
- BaseHandler.parent
一個有效的 OpenerDirector 對象,它能夠被用做用一個不一樣的協議打開,或者處理錯誤.
- BaseHandler.default_open(req)
這個方法不是在 BaseHandler 中被定義的,可是子類必須重寫它若是它們想匹配全部的地址的話.
這個方法若是執行將會被其父 OpenerDirector 調用.它的返回值應當和 OpenerDirector 中的 open() 描述的返回值同樣,是一個類文件對象,或者是 None
.它應當觸發 URLError ,除非一個真正異常的事件發生了( MemoryError 不該該映射到 URLError ).
這個方法將在全部的特殊的協議打開方法前被調用.
- BaseHandler.protocol_open(req)
("protocol" 應當被替換爲協議名稱.)
這個方法不是在 BaseHandler 中被定義的,可是子類必須重寫它若是它們想處理特定協議的地址的話.
這個方法若是被定義,將會被其父 OpenerDirector 調用.它的返回值應當和 OpenerDirector 中的 default_open() 返回值同樣.
- BaseHandler.unknown_open(req)
這個方法不是在 BaseHandler 中被定義的,可是子類必須重寫它若是它們想匹配全部未指定處理器的地址的話.
這個方法若是執行將會被其父 OpenerDirector 調用.它的返回值應當和 OpenerDirector 中的 default_open() 描述的返回值同樣.
- BaseHandler.http_error_default(req, fp, code, msg, hdrs)
這個方法不是在 BaseHandler 中被定義的,可是子類必須重寫它若是它們打算提供全面的錯誤處理支持.當產生錯誤時 OpenerDirector 會自動調用它,而且在其餘正常環境下不該被調用.
req 是一個 Request 對象, fp 是一個帶有 HTTP 錯誤體的類文件對象, code 是三位數錯誤碼, msg 是用戶可見的錯誤碼解釋, hdrs 是帶有頭錯誤信息的映射對象.
返回值和異常應當和 urlopen() 一致.
- BaseHandler.http_error_nnn(req, fp, code, msg, hdrs)
nnn 三位 HTTP 錯誤碼.這個方法不是在 BaseHandler 中被定義的,當它存在於一個子類實例中而且一個對應的 HTTP 錯誤碼出現時它便會被調用.
子類必須重寫這個方法使之可以處理特定的 HTTP 錯誤.
參數,返回值和觸發的異常應當和 http_error_default() 一致.
- BaseHandler.protocol_request(req)
("protocol" 應當被替換爲協議名稱.)
這個方法不是在 BaseHandler 中被定義的,可是子類必須定義它若是它們想預處理給定協議的請求.
這個方法若是被定義,將會被其父 OpenerDirector 調用. req 是一個 Request 對象.返回值應當是一個 Request 對象.
- BaseHandler.protocol_response(req, response)
("protocol" 應當被替換爲協議名稱.)
這個方法不是在 BaseHandler 中被定義的,可是子類必須定義它若是它們想預處理給定協議的響應.是一個對象,這個對象應當實現和 urlopen() 返回值同樣的接口.
HTTPRedirectHandler 對象
注意: 一些 HTTP 重定向須要模塊客戶端代碼的操做.若是是這種狀況,將會觸發 HTTPError .查看 RFC 2616 能夠得到各類重定向代碼的具體含義.
HTTPRedirectHandler.redirect_request(req, fp, code, msg, hdrs, newurl)
返回一個 Request 或者 None
來響應重定向.當從服務器收到重定向時, http_error_30() 的默認實現會調用這個方法.若是要發生一個重定向,將會返回一個新的 Request 以容許 http_error_30()
執行重定向到新的地址.另外,若是沒有其它處理器嘗試處理這個地址,就會觸發 HTTPError ,或者返回 None
你不得不使用一個可能的另外的處理器[if no other handler should try to handle this URL, or return None if you can’t but another handler might.].
注意:這個方法的默認實現並未嚴格按照 RFC 2616 標準,也就是說301和302響應對
POST
請求禁止在未經用戶確認的狀況下自動重定向.實際上,瀏覽器會自動容許這些重定向響應,並將POST
改成GET
,默認實現再現了這種行爲.
Location:
或者 URI:
地址.當收到 HTTP 'moved permanently' 響應時這個方法被其父 OpenerDirector 調用.HTTPRedirectHandler.http_error_307(req, fp, code, msg, hdrs)
與 http_error_301() 同樣,可是稱爲 'temporary redirect' 響應.
HTTPCookieProcessor 對象
HTTPCookieProcessor 有一個屬性:
ProxyHandler 對象
protocol_open
函數,這個函數將經過調用 request.set_proxy()
修改請求使之經過代理,而且調用在處理鏈中的下一個處理器使協議生效[call the next handler in the chain to actually execute the protocol].HTTPPasswordMgr 對象
這些方法在 HTTPPasswordMgr 和 HTTPPasswordMgrWithDefaultRealm 對象可用.
(None,None)
.None
域中尋找.AbstractBasicAuthHandler 對象
"python.org"
)或者是一個包含受權成分的 URI .不管如何,受權都不能包含用戶信息成分(所以, "python.org"
和 "python.org:80"
是能夠的, "joe:password@python.org"
則不能夠).HTTPBasicAuthHandler 對象
ProxyBasicAuthHandler 對象
AbstractDigestAuthHandler 對象
HTTPDigestAuthHandler 對象
ProxyDigestAuthHandler 對象
HTTPHandler 對象
req.has_data()
.HTTPSHandler 對象
req.has_data()
.FileHandler 對象
CacheFTPHandler 對象
CacheFTPHandler 對象相對 FTPHandler 對象有兩個額外的方法:
UnknownHandler 對象
HTTPErrorProcessor 對象
protocol_error_code
處理方法.最終,若是沒有其餘處理器處理錯誤的話, urllib2.HTTPDefaultErrorHandler 將會觸發一個 HTTPError .獲取 python.org 主頁並顯示前100個字節的例子:
import urllib2 f = urllib2.urlopen('http://www.python.org/') print f.read(100)
在這裏咱們發送一個數據包到 CGI 的標準輸入而且讀取它返回給咱們的數據.注意例子僅僅在 Python 程序支持 SSL 的條件下才能正常工做.
import urllib2 req = urllib2.Request(url='https://localhost/cgi-bin/test.cgi', data='This data is passed to stdin of the CGI') f = urllib2.urlopen(req) print f.read()
上例示例 CGI 使用的代碼:
#!/usr/bin/env python import sys data = sys.stdin.read() print 'Content-type: text-plain\n\nGot Data: "%s"' % data
使用基本的 HTTP 驗證:
import urllib2
# Create an OpenerDirector with support for Basic HTTP Authentication... auth_handler = urllib2.HTTPBasicAuthHandler() auth_handler.add_password(realm='PDQ Application', uri='https://mahler:8092/site-updates.py', user='klem', passwd='kadidd!ehopper') opener = urllib2.build_opener(auth_handler) # ...and install it globally so it can be used with urlopen. urllib2.install_opener(opener) urllib2.urlopen('http://www.example.com/login.html')
build_opener() 提供了許多默認處理器,包括了一個 ProxyHandler .默認地, ProxyHandler 使用名稱爲 <scheme>_proxy
的環境變量, <scheme>
是相關的地址方案.例如, http_proxy 環境變量被讀取以得到 HTTP 代理的地址.
這個例子替換了默認的 ProxyHandler,使用了一個帶有編程支持的代理地址的對象,而且使用 ProxyBasicAuthHandler 添加了代理認證支持.
proxy_handler = urllib2.ProxyHandler({'http': 'http://www.example.com:3128/'}) proxy_auth_handler = urllib2.ProxyBasicAuthHandler() proxy_auth_handler.add_password('realm', 'host', 'username', 'password') opener = urllib2.build_opener(proxy_handler, proxy_auth_handler) # This time, rather than install the OpenerDirector, we use it directly: opener.open('http://www.example.com/login.html')
添加 HTTP 頭:
在 Request 構造函數中使用 headers 參數,或者:
import urllib2 req = urllib2.Request('http://www.example.com/') req.add_header('Referer', 'http://www.python.org/') r = urllib2.urlopen(req)
OpenerDirector 自動地添加 User-Agent 頭到每個 Request 中.爲了改變它:
import urllib2 opener = urllib2.build_opener() opener.addheaders = [('User-agent', 'Mozilla/5.0')] opener.open('http://www.example.com/')
另外要記住的是,當 Request 傳遞到 urlopen() (或者 OpenerDirector.open())時,一些標準頭(Content-Length, Content-Type and Host)也會被添加.