urllib和urllib2的區別及用

首先來看一下他們的區別php

urllib和urllib2html

  • urllib2能夠接受一個Request類的實例來設置URL請求的headers,urllib僅能夠接受URL。這意味着,你不能夠經過urllib模塊假裝你的User Agent字符串等(假裝瀏覽器)。
  • urllib提供urlencode方法用來GET查詢字符串的產生,而urllib2沒有。這是爲什麼urllib常和urllib2一塊兒使用的緣由。
  • urllib2模塊比較優點的地方是urllib2.urlopen能夠接受Request對象做爲參數,從而能夠控制HTTP Request的header部。
  • 可是urllib.urlretrieve函數以及urllib.quote等一系列quote和unquote功能沒有被加入urllib2中,所以有時也須要urllib的輔助。

httplibpython

httplib實現了HTTP和HTTPS的客戶端協議,通常不直接使用,在python更高層的封裝模塊中(urllib,urllib2)使用了它的http實現。web

 

urllib簡單用法

 

urllib.urlopen(url[, data[, proxies]]) :   請求數據ajax

    建立一個表示遠程url的類文件對象,而後像本地文件同樣操做這個類文件對象來獲取遠程數據。參數url表示遠程數據的路徑,通常是網址;參數data表示以post方式提交到url的數據(玩過web的人應該知道提交數據的兩種方式:post與get。若是你不清楚,也沒必要太在乎,通常狀況下不多用到這個參數);參數proxies用於設置代理。urlopen返回一個類文件對象,他提供了以下方法:瀏覽器

  •     read(),readline(),readlines(), fileno(), close():這些方法的使用方式與文件對象徹底同樣;
  •     info():返回一個httplib.HTTPMessage對象,表示遠程服務器返回的頭信息;
  •     getcode():返回Http狀態碼。若是是http請求,200表示請求成功完成;404表示網址未找到;
  •     geturl():返回請求的url;
import urllib  
google = urllib.urlopen('http://www.google.com')    
print 'http header:/n', google.info() #獲取服務器返回的頭信息   
print 'http status:', google.getcode() # 獲取返回的狀態碼   
print 'url:', google.geturl()    # 獲取請求的url
for line in google: # 就像在操做本地文件 print line, google.close()

 

>>> import urllib.request
>>> res = urllib.request.urlopen('http://localhost/')
>>> res.getheaders()
[('Date', 'Wed, 20 Jan 2016 14:27:42 GMT'), ('Server', 'Apache/2.4.16 (Win32) OpenSSL/1.0.1p PHP/5.6.12'), ('Content-Length', '5849'), 
('Connection', 'close'), ('Content-Type', 'text/html;charset=UTF-8')]

urllib.urlretrieve(url[, filename[, reporthook[, data]]]):  下載文件服務器

    urlretrieve方法直接將遠程數據下載到本地。參數filename指定了保存到本地的路徑(若是未指定該參數,urllib會生成一個臨時文件來保存數據);參數reporthook是一個回調函數,當鏈接上服務器、以及相應的數據塊傳輸完畢的時候會觸發該回調。咱們能夠利用這個回調函數來顯示當前的下載進度,下面的例子會展現。參數data指post到服務器的數據。該方法返回一個包含兩個元素的元組(filename, headers),filename表示保存到本地的路徑,header表示服務器的響應頭。下面經過例子來演示一下這個方法的使用,這個例子將新浪首頁的html抓取到本地,保存在D:/sina.html文件中,同時顯示下載的進度。  cookie

def cbk(a, b, c):    
    '''''''回調函數  
    @a: 已經下載的數據塊  
    @b: 數據塊的大小  
    @c: 遠程文件的大小  
    '''    
    per = 100.0 * a * b / c    
    if per > 100:    
        per = 100    
    print '%.2f%%' % per    
    
url = 'http://www.sina.com.cn'    
local = 'd://sina.html' #本地存放的地址   
urllib.urlretrieve(url, local, cbk)    

      上面介紹的兩個方法是urllib中最經常使用的方法,這些方法在獲取遠程數據的時候,內部會使用URLopener或者 FancyURLOpener類。做爲urllib的使用者,咱們不多會用到這兩個類,這裏我不想多講。若是對urllib的實現感興趣, 或者但願urllib支持更多的協議,能夠研究這兩個類。在Python手冊中,urllib的做者還列出了這個模塊的缺陷和不足,感興趣的同窗能夠打開 Python手冊瞭解一下。app

       urllib中還提供了一些輔助方法,用於對url進行編碼、解碼。url中是不能出現一些特殊的符號的,有些符號有特殊的用途。咱們知道以get方式提交數據的時候,會在url中添加key=value這樣的字符串,因此在value中是不容許有'=',所以要對其進行編碼;與此同時服務器接收到這些參數的時候,要進行解碼,還原成原始的數據。這個時候,這些輔助方法會頗有用:socket

  • urllib.quote(string[, safe]):對字符串進行編碼。參數safe指定了不須要編碼的字符;
  • urllib.unquote(string) :對字符串進行解碼;
  • urllib.quote_plus(string[,safe]) :與urllib.quote相似,但這個方法用'+'來替換' ',而quote用'%20'來代替' '
  • urllib.unquote_plus(string) :對字符串進行解碼;
  • urllib.urlencode(query[, doseq]):將dict或者包含兩個元素的元組列表轉換成url參數。例如 字典{'name': 'dark-bull', 'age': 200}將被轉換爲"name=dark-bull&age=200"
  • urllib.pathname2url(path):將本地路徑轉換成url路徑;
  • urllib.url2pathname(path):將url路徑轉換成本地路徑; 
  1. data = 'name = ~a+3'    
  2.     
  3. data1 = urllib.quote(data)    
  4. print data1 # result: name%20%3D%20%7Ea%2B3    
  5. print urllib.unquote(data1) # result: name = ~a+3    
  6.     
  7. data2 = urllib.quote_plus(data)    
  8. print data2 # result: name+%3D+%7Ea%2B3    
  9. print urllib.unquote_plus(data2)    # result: name = ~a+3    
  10.     
  11. data3 = urllib.urlencode({ 'name''dark-bull''age'200 })    
  12. print data3 # result: age=200&name=dark-bull    
  13.     
  14. data4 = urllib.pathname2url(r'd:/a/b/c/23.php')    
  15. print data4 # result: ///D|/a/b/c/23.php    
  16. print urllib.url2pathname(data4)    # result: D:/a/b/c/23.php   

  

 

urllib2簡單用法

 

  1. #!/usr/bin/env python  
  2.     import urllib2  
  3.     req = urllib2.Request("http://www.douban.com")  
  4.     response = urllib2.urlopen(req)  
  5.     html = response.read()  
  6.     print html  

 

一、urllib2.Request()的功能是構造一個請求信息,返回的req就是一個構造好的請求

二、urllib2.urlopen()的功能是發送剛剛構造好的請求req,並返回一個文件類的對象response,包括了全部的返回信息。

三、經過response.read()能夠讀取到response裏面的html,經過response.info()能夠讀到一些額外的信息

有時你會碰到,程序也對,可是服務器拒絕你的訪問。這是爲何呢?問題出在請求中的頭信息(header)。 有的服務端有潔癖,不喜歡程序來觸摸它。這個時候你須要將你的程序假裝成瀏覽器來發出請求。請求的方式就包含在header中。
常見的情形:

  1. import urllib  
  2. import urllib2  
  3. url = 'http://www.someserver.com/cgi-bin/register.cgi'  
  4. user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'# 將user_agent寫入頭信息  
  5. values = {'name' : 'who','password':'123456'}  
  6. headers = { 'User-Agent' : user_agent }  
  7. data = urllib.urlencode(values)  
  8. req = urllib2.Request(url, data, headers)  
  9. response = urllib2.urlopen(req)  
  10. the_page = response.read()  

 

urllib2和urllib配合使用:

GET方法

例如百度:

百度是經過http://www.baidu.com/s?wd=XXX 來進行查詢的,這樣咱們須要將{‘wd’:’xxx’}這個字典進行urlencode

 

  1. import urllib   
  2. import urllib2    
  3. url = 'http://www.baidu.com/s'   
  4. values = {'wd':'D_in'}     
  5. data = urllib.urlencode(values)  
  6. print data   
  7. url2 = url+'?'+data  
  8. response = urllib2.urlopen(url2)    
  9. the_page = response.read()   
  10. print the_page  

 

POST方法

 

  1. import urllib  
  2. import urllib2  
  3. url = 'http://www.someserver.com/cgi-bin/register.cgi'  
  4. user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' //將user_agent寫入頭信息  
  5. values = {'name' : 'who','password':'123456'}      //post數據  
  6. headers = { 'User-Agent' : user_agent }  
  7. data = urllib.urlencode(values)                   //對post數據進行url編碼  
  8. req = urllib2.Request(url, data, headers)  
  9. response = urllib2.urlopen(req)  
  10. the_page = response.read()  

 

urllib2帶cookie的使用

 

  1. #coding:utf-8  
  2. import urllib2,urllib  
  3. import cookielib  
  4.    
  5. url = r'http://www.renren.com/ajaxLogin'  
  6.    
  7. #建立一個cj的cookie的容器  
  8. cj = cookielib.CookieJar()  
  9. opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))  
  10. #將要POST出去的數據進行編碼  
  11. data = urllib.urlencode({"email":email,"password":pass})  
  12. r = opener.open(url,data)  
  13. print cj  

 

httplib

httplib是一個相對底層的http請求模塊,其上有專門的包裝模塊,如urllib內建模塊,goto等第三方模塊,可是封裝的越高就越不靈活,好比urllib模塊裏請求錯誤時就不會返回結果頁的內容,只有頭信息,對於某些須要檢測錯誤請求返回值的場景就不適用,因此就得用這個模塊了。

一、class httplib.HTTPConnection

說明:該類用於建立一個http類型的請求連接
原型:
HTTPConnection(host[, port[, strict[, timeout]]])
host: 請求的服務器host,不能帶http://開頭
port: 服務器web服務端口
strict: 是否嚴格檢查請求的狀態行,就是http1.0/1.1 協議版本的那一行,即請求的第一行,默認爲False,爲True時檢查錯誤會拋異常
timeout: 單次請求的超時時間,沒有時默認使用httplib模塊內的全局的超時時間

  1.     實例:    
  2.     conn1 = HTTPConnection('www.baidu.com:80')    
  3.     conn2 = HTTPconnection('www.baidu.com',80)    
  4.     conn3 = HTTPConnection('www.baidu.com',80,True,10)    
  5.     錯誤實例:    
  6.     conn3 = HTTPConnection('www.baidu.com:80',True,10)  

 

返回:HTTPConnection類會實例並返回一個HTTPConnection對象

 

二、class httplib.HTTPSConnection

說明:該類用於建立一個https類型的請求連接
原型:
HTTPSConnection(host[, port[, key_file[, cert_file[, strict[, timeout]]]]])
key_file:一個包含PEM格式的私鑰文件
cert_file:一個包含PEM格式的認證文件
other:其它同http參數

實例:

 

conn3 = HTTPSConnection('accounts.google.com',443,key_file,cert_file,True,10) 

返回:一樣返回一個HTTPSConnection對象
注意:要建立https連接,必需要保證底層的socket模塊是支持ssl的編譯模式,即編譯時ssl選項的開關是開着的

 

 三、HTTPConnection對象request方法:

說明:發送一個請求
原型:
conn.request(method, url[, body[, headers]])
method: 請求的方式,如'GET','POST','HEAD','PUT','DELETE'等
url: 請求的網頁路徑。如:'/index.html'
body: 請求是否帶數據,該參數是一個字典
headers: 請求是否帶頭信息,該參數是一個字典,不過鍵的名字是指定的http頭關鍵字
實例:

 

  1. conn.request('GET''/''', {'user-agent':'test'}) 

 

返回:無返回,其實就是相對於向服務其發送數據,可是沒有最後回車


四、HTTPConnection對象getresponse方法
  說明:獲取一個http響應對象,至關於執行最後的2個回車

  原型/實例:

 

  1. res = conn.getresponse()  

返回:HTTPResponse對象


五、HTTPConnection對象close()方法
  說明:關閉指定的httpconnect連接

  1. conn.close() 

六、HTTPResponse對象read方法
  說明:得到http響應的內容部分,即網頁源碼
  原型:
  body = res.read([amt])
  amt: 讀取指定長度的字符,默認爲空,即讀取全部內容
  實例:

  1. body = res.read()    
  2. pbody = res.read(10) 

返回:網頁內容字符串


七、HTTPResponse對象的其它方法或屬性
  方法:
  getheaders()
    得到全部的響應頭內容,是一個元組列表[(name,value),(name2,value2)]
  getheader(name[,default])
    得到指定的頭內容
  fileno()
    socket的fileno

  屬性:
  msg
    全部的頭信息,和getheaders方法同樣,只不過這個是原始未處理的字符串
  status
    當次請求的狀態
  version
    當次請求的http協議版本,10是http1.0, 11是http/1.1
  reason
    當次請求的結果的表述內容,200是ok,404是Not Found

整體實例:

  1. #!/usr/bin/env python      
  2. # -*- coding: utf-8 -*-      
  3. import httplib    
  4. import urllib    
  5.     
  6. def sendhttp():    
  7.     data = urllib.urlencode({'@number'12524'@type''issue''@action''show'})       
  8.     headers = {"Content-type""application/x-www-form-urlencoded",    
  9.                "Accept""text/plain"}    
  10.     conn = httplib.HTTPConnection('bugs.python.org')    
  11.     conn.request('POST''/', data, headers)    
  12.     httpres = conn.getresponse()    
  13.     print httpres.status    
  14.     print httpres.reason    
  15.     print httpres.read()               
  16.                   
  17. if __name__ == '__main__':      
  18.     sendhttp()   
相關文章
相關標籤/搜索