前面已經介紹過urllib庫(點此檢視),urllib2與其類似,也是Python中用于請求url相關操作的内置庫。
urllib2.urlopen(url[, data[, timeout[, cafile[, capath[, cadefault[, context]]]]])
這個函數可以像urllib.urlopen()那樣以url做參數。也能以Request執行個體為參數,即用一個Request對象(下文構造方法)來映射你提出的HTTP請求,在它最簡單的使用形式中你将用你要請求的位址建立一個Request對象,這個Request對象中可以設定傳輸資料、headers等。通過調用urlopen并傳入Request對象,将傳回一個file-like對象。urllib2還提供了接口來處理一般情況,例如:基礎驗證,cookies,代理和其他,它們通過handlers和openers的對象實作。
在HTTP請求時,允許你做額外的兩件事。首先是你能夠發送data表單資料,其次你能夠傳送額外的關于資料或發送本身的資訊("metadata")到伺服器,此資料作為HTTP的"headers"來發送。接下來讓我們看看這些如何發送的吧:
Data資料
發送data資料的方式有兩種,GET和POST方式。具體差別參見文章淺談HTTP中Get與Post的差別。
python模拟GET方式基本上對url做些字元串的拼接就可以了,有時也會用到urllib.urlencode()函數。當使用urlopen()時沒有傳入data參數,預設的是GET方式進行請求。
python模拟POST方式,需要引入data參數。data資料會發送到URL(多為html中表單action屬性的值,即接受資料并作出反應的URL,如php、jsp、cgi等)。使用python模拟post送出HTML表單,需要編碼成标準形式。然後做為參數傳到Request對象,編碼工作使用urllib.urlencode()函數。
import urllib,urllib2 action_url="http://httpbin.org/post"#用于測試post的網址,傳回送出的資料 values={'name':"alice",'age':20} data=urllib.urlencode(values)#對表單資料編碼 rqst=urllib2.Request(action_url,data) response=urllib2.urlopen(rqst)#模拟送出表單資料到url并獲得響應 print response.read()
Headers
有一些站點不喜歡被程式(非人為通路)通路,或者發送不同版本的内容到不同的浏覽器。預設的urllib2把自己作為“Python-urllib/x.y”(x和y是Python主版本和次版本号,例如Python-urllib/2.5),
這個身份可能會讓站點迷惑,或者幹脆不工作。浏覽器确認自己身份是通過User-Agent頭,當你建立了一個請求對象,你可以給他一個包含頭資料的字典。下面的例子發送跟上面一樣的内容,但把自身模拟成Internet Explorer。import urllib import urllib2 url = 'http://www.weibo.cn/' user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' h = { 'User-Agent' : user_agent } req = urllib2.Request(url,headers=h) response = urllib2.urlopen(req) print response.read()
info and geturl
urlopen傳回的應答對象response(或者HTTPError執行個體)有兩個很有用的方法info()和geturl()
geturl :這個傳回擷取的真實的URL,這個很有用,因為urlopen(或者opener對象使用的)或許會有重定向。擷取的URL或許跟請求URL不同。
info:這個傳回對象的字典對象,該字典描述了擷取的頁面情況。通常是伺服器發送的特定頭headers。目前是httplib.HTTPMessage 執行個體。經典的headers包含"Content-length","Content-type",和其他。
urllib2.Request(url[, data][, headers][, origin_req_host][, unverifiable])
用于構造Request對象,可以傳遞data資料,添加請求頭(headers)等,構造好後作為urllib2.urlopen()的參數。
Openers和Handlers
當你擷取一個URL你使用一個opener(一個urllib2.OpenerDirector的執行個體),正常情況下,我們使用預設opener 進行urlopen()
但你能夠建立個性的openers,Openers使用處理器handlers,所有的“繁重”工作由handlers處理。
每個handlers知道如何通過特定協定打開URLs,或者如何處理URL打開時的各個方面,例如HTTP重定向或者HTTP cookies。如果你希望用特定處理器擷取URLs你會想建立一個openers,例如擷取一個能處理cookie的opener,或者擷取一個不重定向的opener。
要建立一個自定義opener,可以執行個體化一個OpenerDirector,然後調用不斷調用add_handler(some_handler_instance);
同樣,也可以使用build_opener,這是一個更加友善的函數,用來建立opener對象,他隻需要一次函數調用。build_opener預設添加幾個處理器,但提供快捷的方法來添加或更新預設處理器。其他的處理器handlers你或許會希望處理代理,驗證,和其他常用但有點特殊的情況。
install_opener 用來建立(全局)預設opener。這個表示調用urlopen将使用你安裝的opener。
Opener對象有一個open方法,該方法可以像urlopen函數那樣直接用來擷取urls:通常不必調用install_opener,除了為了友善。
具體問題可以參考文章:urllib2自定義opener詳解。