Python Urllib2使用

Python Urllib2使用


我們先看下Python對於Urllib2的解釋:

Intro代碼  收藏代碼
  1. urllib2:An extensible library for opening URLs using a variety of protocols  

  2. The urllib2(http://docs.python.org/2/library/urllib2.html) module defines functions and classes which help in opening URLs (mostly HTTP) in a complex world — basic and digest authentication, redirections, cookies and more.  


簡單的說,urllib2就是簡單版本的HttpClient,能夠處理HTTP請求,我們先看下urllib2提供的功能:

Python代碼  收藏代碼
  1. urllib2.urlopen(url[, data][, timeout])  

請求url,獲得請求數據,url參數可以是個String,也可以是個Request參數

要熟悉Python的這種參數表達方式,[]表示可選項,這種表示方法簡單清楚,描述方式相當不錯。

沒有data參數時爲GET請求,設置data參數時爲POST請求,另外data格式必須爲application/x-www-form-urlencodedurllib.urlencode()能夠設置請求參數的編碼

timeout設置請求阻塞的超時時間,如果沒有設置的話,會使用全局默認timeout參數;該參數只對HTTPHTTPSFTP生效


Python代碼  收藏代碼
  1. class OpenerDirector  

管理一系列的Handler,這些handler都有自己的功能實現和協議,後面會提到大量的Handler功能



Python代碼  收藏代碼
  1. urllib2.build_opener([handler, ...])  

返回OpenerDirector實例,實現了BaseHandler都可以生成Handler實例。Python已經內建許多的Handler,你可以替換或者添加新的Handler


內建Handler如下:

Python代碼  收藏代碼
  1. ProxyHandler:處理代理操作  

  2. UnknownHandler:Raise URLError異常  

  3. HTTPHandler:處理HTTP的GET和POST操作  

  4. HTTPDefaultErrorHandler:處理HTTP Error的通用處理,所有的響應都會拋出HTTPError異常  

  5. HTTPRedirectHandler:處理HTTP重定向操作,如301、302、303等和HEAD請求的307都會執行重定向操作  

  6. FTPHandler:處理FTP操作  

  7. FileHandler:處理文件  

  8. HTTPErrorProcessor:處理非200異常  


除去上面這些Handlerurllib2還有一些其它的Handler可供選擇,這些Handler都能根據名稱知曉其功能,不細作解釋,包括但不僅限於:

Python代碼  收藏代碼
  1. HTTPCookieProcessor:處理cookie  

  2. HTTPBasicAuthHandler:處理Auth  

  3. ProxyBasicAuthHandler:處理Proxy和Auth  

  4. HTTPDigestAuthHandler:處理DigestAuth  

  5. ProxyDigestAuthHandler:處理ProxyDigest  

  6. HTTPSHandler:處理HTTPS請求  

  7. CacheFTPHandler:比FTPHandler多點功能。  


看下urllib2對於opener的使用:

Python代碼  收藏代碼
  1. urllib2.install_opener(opener)  

定義全局的OpenerDirector,如果執行這個方法,會把自己定義的Handler用在後續的URL處理上。



Urllib2的異常定義:

Python代碼  收藏代碼
  1. urllib2.URLError:  

  2. urllib2.HTTPError:  

這兩個異常都是IOError的子類,對於Python的異常定義,大家都不是很滿意,在urllib2中也不例外。


在上面提到urlopen的參數Request,這個Request類能更加豐富請求的內容:

Python代碼  收藏代碼
  1. class urllib2.Request(url[, data][, headers][, origin_req_host][, unverifiable])  

urldata的內容和前面的一致,添加了headers的信息,header的內容可以參考http://isilic.iteye.com/blog/1801072

origin_req_host應該是請求的服務器Host地址,unverifiable參數表明請求是否可驗證


urllib2的主要類和方法就這麼多了,看起來還是很好入手的,下面我們來直接使用下urllib2,例程包括但不限於官網:

Python代碼  收藏代碼
  1. import urllib2  

  2. f = urllib2.urlopen('http://www.python.org/')  

  3. print f.read(100)  

這個用法最簡單,直接使用即可,對於大部分的url請求都可以使用這個方法。



Python代碼  收藏代碼
  1. import urllib2  

  2. req = urllib2.Request(url='https://localhost/cgi-bin/test.cgi',data='Committed Data')  

  3. f = urllib2.urlopen(req)  

  4. print f.read()  

使用Request參數來發送請求。



使用Request來進行更復雜的操作:

Python代碼  收藏代碼
  1. import urllib  

  2. import urllib2  

  3. url = 'http://www.server.com/cgi-bin/register.cgi'

  4. user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'

  5. values = {'name' : 'Michael','language' : 'Python' }  

  6. headers = { 'User-Agent' : user_agent }  

  7. data = urllib.urlencode(values)  

  8. req = urllib2.Request(url, data, headers)  

  9. f = urllib2.urlopen(req)  

  10. print f.read()  

我們使用Request對象,設定了user_agent,對於某些Header需要注意,Server或者應用會對這些值做檢查。

在使用 REST 接口時,Server 會檢查Content-Type字段,用來確定 HTTP Body 中的內容該怎樣解析。

常見的取值有:

Python代碼  收藏代碼
  1. application/xml :在 XML RPC,如 RESTful/SOAP 調用時使用  

  2. application/json :在 JSON RPC 調用時使用  

  3. application/x-www-form-urlencoded :瀏覽器提交 Web 表單時使用  



Handler中有處理Redirecthandler,如果想確認是否跳轉,確認下responseurl是否和請求url一致即可。


Python代碼  收藏代碼
  1. import urllib2  

  2. request_url = "http://www.google.copm"

  3. response = urllib2.urlopen(request_url)  

  4. redirected = response.geturl() == request_url  

如果不想自動Redirect,或者想在Redirect過程中添加些自己的動作,可以通過下面兩種途徑完成:

1:使用更低層次的httplib

2:使用自定義的HTTPRedirectHandler



Proxy的使用相當廣泛,對於單個應用來說,爬蟲是很容易被封禁,如果使用Proxy模式,就能降低被封的風險,所以有需求的同學需要仔細看下Python urllib2對於Proxy的使用:


Python代碼  收藏代碼
  1. import urllib2  

  2. proxy_handler = urllib2.ProxyHandler({'http': '127.0.0.1:80'})  

  3. opener = urllib2.build_opener(proxy_handler)  

  4. urllib2.install_opener(opener)  

  5. f = urllib2.urlopen('http://www.google.com')  

  6. print f.read()  

注意這個Proxy會將proxy_handler作爲全局的ProxyHandler,這個未必是我們需要的,如果我們需要使用不同的Proxy,這個設置就有問題,需要修改爲以下Proxy使用方式:


Python代碼  收藏代碼
  1. import urllib2  

  2. proxy_handler = urllib2.ProxyHandler({'http': '127.0.0.1:80'})  

  3. opener = urllib2.build_opener(proxy_handler)  

  4. f = opener.open(url)  

  5. print f.read()  


對於cookie的處理也是有Handler自動處理的:


Python代碼  收藏代碼
  1. import urllib2  

  2. import cookielib  

  3. cookies = cookielib.CookieJar()  

  4. opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookies))  

  5. response = opener.open('http://www.google.com')  

  6. for cookie in cookies:  

  7. if cookie.name == 'cookie_spec':  

  8. print cookie.value  

處理cookie是一般是cookielibHTTPCookieProcessor一起使用


使用Basic HTTP Authentication

Python代碼  收藏代碼
  1. import urllib2  

  2. auth_handler = urllib2.HTTPBasicAuthHandler()  

  3. auth_handler.add_password(realm='PDQ Application',  

  4.                          uri='https://mahler:8092/site-updates.py',  

  5.                          user='klem',  

  6.                          passwd='kadidd!ehopper')  

  7. opener = urllib2.build_opener(auth_handler)  

  8. urllib2.install_opener(opener)  

  9. f = urllib2.urlopen('http://www.server.com/login.html')  

  10. print f.read()  


debug log level使用

Python代碼  收藏代碼
  1. import urllib2  

  2. httpHandler = urllib2.HTTPHandler(debuglevel=1)  

  3. httpsHandler = urllib2.HTTPSHandler(debuglevel=1)  

  4. opener = urllib2.build_opener(httpHandler, httpsHandler)  

  5. urllib2.install_opener(opener)  

  6. response = urllib2.urlopen('http://www.google.com')  

可以看到urllib2抓包時打印的內容,方便調試分析。


最後還有一點,使用urllib2.urlopen()時,urllib2有實際發送請求和獲取響應嗎?那麼read()函數又進行了哪些操作呢?http://stackoverflow.com/questions/3009144/does-urllib2-urlopen-actually-fetch-the-page/3009697#3009697 。這篇文章能夠很好的解決你心中的疑惑,大家仔細閱讀下。


urllib2的使用就暫時到這裏,其實urllib2已經給我們提供了基礎的內容使用,對於擴展功能,也有很好的框架可以擴展;對於我們來說已經能夠很好的進行工作啦。如果說這些功能還不能滿足要求或者擴展也不能實現時,你只能使用httplib,或者自己實現並貢獻python代碼,相信對於技術提升還是很明顯的。

最後還有一點,Python官方也提供了urllib2的源碼,大家如果有什麼不明白的地方,源碼的準確性總是第一位的,源碼的地址見這裏:http://hg.python.org/cpython/file/2.7/Lib/urllib2.py  沒事翻翻Python的源碼,對於Python本身的知識積累也是不錯的。


【轉載】:轉載自http://isilic.iteye.com/blog/1806403

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章