天天看點

python urllib2介紹

前面已經介紹過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詳解。

繼續閱讀