文章目錄
- 1、抓取簡單網頁
- 2、進行檔案下載
- 3、urllib 基本使用
- 4、urllib2 基本使用
最近又來學習python了,可惜沒有怎麼將其用於工作中,只能利用空餘時間來玩玩。
1、抓取簡單網頁
# coding=utf-8import urllib2response = urllib2.urlopen('http://www.pythonclub.org/python-network-application/observer-spider')html = response.read()print html
簡寫為:
# coding=utf-8import urllib2content = urllib2.urlopen('http://www.pythonclub.org/python-network-application/observer-spider').read()print content
或:urllib
# coding=utf-8import urlliburl = 'http://www.pythonclub.org/python-network-application/observer-spider'req = urllib.urlretrieve(url,'julius.html')#儲存為julius.html
運行後得到:
>>> ================================ RESTART ================================>>> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh" lang="zh" dir="ltr"><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="verify-v1" content="b8lZkhAZ0gBeWqZkVdAxNe+LWoK1QM1OYztpvC7Sqic=" /> <title> 用python爬蟲抓站的一些技巧總結 zz [Python俱樂部] </title> <meta name="generator" content="DokuWiki" /><meta name="robots" content="index,follow" /><meta name="date" content="2011-02-11T15:31:55+0800" /><meta name="keywords" content="python-network-application,observer-spider" /><link rel="search" type="application/opensearchdescription+xml" href="/lib/exe/opensearch.php" title="Python俱樂部" />。。。。。。
如果遇到
raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)HTTPError: HTTP Error 403: Forbidden
則是對方網頁禁止被抓取了,需要類比瀏覽器抓取
import urllib2headers = {'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'}#出現urllib2.HTTPError: HTTP Error 403: Forbidden錯誤是由於網站禁止爬蟲,在請求加上頭資訊,偽裝成瀏覽器訪問解決url = 'http://blog.csdn.net/julius_lee/article/details/7682909'req = urllib2.Request(url,headers = headers)content = urllib2.urlopen(req).read()print content.decode('u8')
運行後得到:
>>> ================================ RESTART ================================>>> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>python 學習記錄(2)—re Regex模組的使用 - julius_lee的成長記錄 - 部落格頻道 - CSDN.NET</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="description" content="1.1 建立與使用In [87]: import reIn [88]: re_string = {{(.*?)}}In [89]: test_string = this {{is}} a test {{string}} and {{may be}} [wrong], ok?In [90]: for match in re.findall(re_string" />
2、進行檔案下載
方法一:urllib
import urlliburl = 'http://music.baidu.com/data/music/file?link=http://zhangmenshiting.baidu.com/data2/music/44799414/447992771372651261320.mp3?xcode=760fd59b6ae51718c0bb6b6933610b20a4f508beeec48fde'urllib.urlretrieve(url,'E:\\study\\python\\tmp\\123.mp3')
抓取了百度MP3 的歌曲並儲存在
E:\\study\\python\\tmp\\
命名為123.MP3
方法二:requests
# coding=utf-8import requestsurl = 'http://music.baidu.com/data/music/file?link=http://zhangmenshiting.baidu.com/data2/music/44799414/447992771372651261320.mp3?xcode=760fd59b6ae51718c0bb6b6933610b20a4f508beeec48fde' print "downloading with requests"r = requests.get(url) with open("1234_requests.mp3", "wb") as code: code.write(r.content)
方法三:urllib2
# coding=utf-8import urllib2url = 'http://music.baidu.com/data/music/file?link=http://zhangmenshiting.baidu.com/data2/music/44799414/447992771372651261320.mp3?xcode=760fd59b6ae51718c0bb6b6933610b20a4f508beeec48fde' print "downloading with urllib2"r = urllib2.urlopen(url)data = r.read() with open("1234_urllib2.mp3", "wb") as code: code.write(data)
缺點是沒有進度提示,需要確定程式運行完成,解決辦法:
def abc(a,b,c): ''' a: num b: size c: total ''' process = 100.0*a*b/c if process > 100: process = 100 print '%.2f%%' %process
儲存文本的方法:
content=r.read()print "字串長度:",len(content)#找開一個文字檔fp=open("163.txt","w")#寫入資料fp.write(content)fp.close();
或者:
with open('python.html','w') as code: code.write(data)
問題:如何進行選擇?有何區別?
可以把urllib2當作urllib的擴增,比較明顯的優勢是urllib2.urlopen可以接受Request對象作為參數,從而可以控制HTTP Request的header;
做HTTP Request時應當盡量使用urllib2庫,但是urllib.urlretrieve函數以及urllib.quote等一系列quote和unquote功能沒有被加入urllib2中,因此有時也需要urllib的輔助
1、urllib2可以接受一個Request類的執行個體來設定URL請求的headers,urllib僅可以接受URL:這意味著你不可以偽裝你的User Agent字串等。
2、urllib提供urlencode方法用來GET查詢字串的產生,而urllib2沒有。這是為何urllib常和urllib2一起使用的原因。Data同樣可以通過在Get請求的URL本身上面編碼來傳送,urllib.urlencode(data)
urllib:比較簡單,功能相對也比較弱,可以從指定的URL下載檔案,或是對一些字串進行編碼解碼以使他們成為特定的 URL串。
urllib2:它有各種各樣的Handler啊,Processor啊可以處理更複雜的問 題,比如網路認證,使用Proxy 伺服器,使用cookie等等。
HTTP是基於請求和應答機制的--用戶端提出請求,服務端提供應答。urllib2用一個Request對象來映射你提出的HTTP請求,在它最簡單的使用形式中你將用你要請求的地址建立一個Request對象,通過調用urlopen並傳入Request對象,將返回一個相關請求response對象,這個應答對象如同一個檔案對象,所以你可以在Response中調用.read()
3、urllib 基本使用
python urllib的使用介紹
一。該模組的用途:
1。從制定的URL擷取資料
2。對URL字串進行格式化處理
二。__version__='1.17'的urllib模組中的主要函數和類介紹:
1。函數:
(1)def urlopen(url, data=None, proxies=None)
參數說明:
url 符合URL規範的字串(包括http,ftp,gopher,local-file標準)
data 向指定的URL發送的資料字串,GET和POST都可,但必須符合標準格式
格式為key=value&key1=value1....
proxies Proxy 伺服器地址字典,如果未指定,在WINDOWS平台上則依據IE的設定
不支援需要驗證的Proxy 伺服器
例如:proxies = {'http': 'http://www.someproxy.com:3128'}
該例子表示一個httpProxy 伺服器http://www.someproxy.com:3128
函數實現說明:
該函數使用類FancyURLopener從URLopener繼承來的open方法執行具體的操作。
傳回值:
返回一個類似檔案對象的對象(file_like) object
該對象擁有的方法為
read()
readline()
readlines()
fileno()
close()
以上方法同file object的類似方法的使用方法基本一致
info()返回從伺服器傳回的MIME標籤頭
geturl()返回真實的URL,之所以稱為真實,是因為對於某些重新導向的URL,將返回被重定後的。
(2)def urlretrieve(url, filename=None, reporthook=None, data=None):
參數說明:
url 符合URL規範的字串
filename 本地檔案路徑的字串,從URL返回的資料將儲存在該檔案中,如果設定為None
則產生一個臨時檔案
reporthook 一個函數引用,自己可以任意定義該函數的行為,只需要保證函數有三個參數
urlretrieve為這個函數傳遞的三個參數的含義為:
第一個參數為目前為止傳遞的資料區塊數量
第二個參數為每個資料區塊的大小,單位為byte
第三個參數檔案總的大小(某些時候可能為-1)
data 向指定的URL發送的資料字串,GET和POST都可,但必須符合標準格式
格式為key=value&key1=value1....
函數實現說明:
該函數使用類FancyURLopener從URLopener繼承來的retrieve方法執行具體的操作。
傳回值:
返回一個元組 (filename, headers)
filename為參數中的 filename
headers 為從伺服器傳回的MIME標籤頭
(3)def urlcleanup():
參數說明: 無參數
函數實現說明:該函數使用類FancyURLopener從URLopener繼承來的cleanup方法執行具體的操作。
清除使用urlopen或urlretrieve後產生的快取檔案
傳回值: 無傳回值
(4)def quote(s, safe = '/'):
參數說明:
s 需要轉化的字串
safe 需要保留不轉化的字元序列
函數實現說明:
根據rfc 2396規定,URL保留字元為
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |"$" | ","
但是這些字元並不是在所有類型的URL中都保留不轉化,
所以要求使用該函數的時候在轉化不同的URL時設定不同的保留字元
其中在任意部分都不轉化的字元為:大小寫字母,數字,'_','.','-'
對於漢字,也可以使用,但要加上相應的編碼,比如quote(u'蟒蛇'.encode('gb2312'))
該函數會將所有非保留的字元轉化成%xx這樣的形式,其中xx為兩位的十六進位數
傳回值:
轉化後的字串
(5)def quote_plus(s, safe = ''):
參數說明:
s 需要轉化的字串
safe 需要保留不轉化的字元序列
函數實現說明:
與quote函數基本一致,只是把參數s中的空格轉化成'+',而不是%20
傳回值:
轉化後的字串
(6)def unquote(s):
參數說明:
s 需要反向轉化的字串
函數實現說明:
與quote作用相反的解析函數
傳回值:
轉化後的字串
(7)def unquote_plus(s):
s 需要反向轉化的字串
函數實現說明:
與quote_plus作用相反的解析函數
傳回值:
轉化後的字串
(8)def urlencode(query,doseq=0):
參數說明:
query 可以是一個由二元元組做元素的元組,也可以是一個字典
doseq 如何對參數字串化
函數實現說明:
將成對的資料按照URL中的要求組成一個參數字串
例如:
query = (('name','cs'),('age','1'),('height','2'))
re = urllib.urlencode(query)
print re
query1 = {'name':'cs','age':'1','height':'2'}
print urllib.urlencode(query1)
這兩個的效果基本一樣,但字典類型會自動排序,
輸出結果為:
name=cs&age=1&height=2
age=1&name=cs&height=2
doseq參數的意義,文檔太簡短,嘗試了一下,發現在如何字串化上不同
query1 = {'name':'cs','age':('a','b'),'height':'1'}
print urllib.urlencode(query1,1)
print urllib.urlencode(query1,0)
輸出結果為:
age=a&age=b&name=cs&height=1
age=%28%27a%27%2C+%27b%27%29&name=cs&height=1
傳回值:
經過拚接的參數字串
(9)def url2pathname(pathname):
參數說明:
pathname URL字串
函數實現說明:
該函數將根據作業系統確定如何轉化URL中的'/'為'\' ,
然後其他的就和quote行為一樣了(就是將字串傳遞給quote來處理的)
傳回值:
符合本地檔案路徑格式的字串
(10)def pathname2url(pathname):
參數說明:
pathname 符合本地檔案路徑命名的格式的字串
函數實現說明:
該函數將根據作業系統確定如何轉化URL中的'/'為'\' ,
然後其他的就和unquote行為一樣了(就是將字串傳遞給unquote來處理的)
傳回值:
符合URL標準的字串
(註:9,10這兩個函數一般不直接用,而是在提供的以統一的方法定位網路和本地資源的介面函數中使用)
舉例:
#Proxy 伺服器# coding=utf-8import urlliburl = 'http://www.python.org'proxies = {'http':'http://127.0.0.1:8086/'}r = urllib.urlopen(url, proxies=None) #選擇不使用Proxy 伺服器開啟print r.info()print r.getcode()print r.geturl()
輸出:Date: Sun, 07 Jul 2013 02:15:06 GMTServer: Apache/2.2.16 (Debian)Last-Modified: Sat, 06 Jul 2013 21:01:42 GMTETag: "105800d-5245-4e0de1e445980"Accept-Ranges: bytesContent-Length: 21061Vary: Accept-EncodingConnection: closeContent-Type: text/html200http://www.python.org# coding=utf-8import urllibproxies = {'http':'http://127.0.0.1:8087'}url = 'http://www.python.org'r = urllib.urlopen(url, proxies=proxies) #選擇使用Proxy 伺服器開啟print r.info()print r.getcode()print r.geturl()Content-Length: 21061Via: HTTP/1.1 GWA #通過代理Accept-Ranges: bytesVary: Accept-EncodingServer: Apache/2.2.16 (Debian)Last-Modified: Sat, 06 Jul 2013 21:01:42 GMTEtag: "105800d-5245-4e0de1e445980"Date: Sun, 07 Jul 2013 06:35:57 GMTContent-Type: text/html200http://www.python.org
#開啟本地檔案# coding=utf-8import urlliburl = 'file:C:\mywork\workspace\Greetings.java'r = urllib.urlopen(url, proxies=None)print r.info()print r.getcode()print r.geturl()print r.read()
輸出:Content-Type: text/plainContent-Length: 258Last-modified: Thu, 07 Jun 2012 14:50:19 GMTNoneC:%5Cmywork%5Cworkspace%5CGreetings.javaimport javax.swing.*;class Greetings{public static void main(String[] args){String fullName;fullName=JOptionPane.showInputDialog(null,"What is your name?");JOptionPane.showMessageDialog(null,"Nice to meet you,"+fullName+".");System.exit(0);}}
#顯示檔案下載進度import urllibdef abc(a,b,c): ''' a: num b: size c: total ''' process = 100.0*a*b/c if process > 100: process = 100 print '%.2f%%' %process url = 'http://music.baidu.com/data/music/file?link=http://zhangmenshiting.baidu.com/data2/music/44054399/34182398136800320.mp3?xcode=80e3a05147cde7b2674fb0bc532f5d1a19ca7b175bf8482d'urllib.urlretrieve(url,'E:\\study\\python\\tmp\\風吹麥浪.mp3',abc)
輸出並下載檔案完成:0.00%0.10%0.21%0.31%0.41%。。。。100.00%
#get方法params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})f = urllib.urlopen("http://www.musi-cal.com/cgi-bin/query?%s" % params)print f.read()#post方法params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})f = urllib.urlopen("http://www.musi-cal.com/cgi-bin/query", params)print f.read()
#uses an explicitly specified HTTP proxy>>> import urllib>>> proxies = {'http': 'http://proxy.example.com:8080/'}>>> opener = urllib.FancyURLopener(proxies)>>> f = opener.open("http://www.python.org")>>> f.read()
#uses no proxies at all>>> import urllib>>> opener = urllib.FancyURLopener({})>>> f = opener.open("http://www.python.org/")>>> f.read()
4、urllib2 基本使用
urllib2是python的一個擷取url(Uniform ResourceLocators,統一資源定址器)的模組。它用urlopen函數的形式提供了一個非常簡潔的介面。這使得用各種各樣的協議擷取url成為可能。它同時也提供了一個稍微複雜的介面來處理常見的狀況-如基本的認證,cookies,代理,等等。這些都是由叫做opener和handler的對象來處理的。
# coding=utf-8 import urllib2 url = 'http://www.python.org' req = urllib2.Request(url) r = urllib2.urlopen(req) data = r.read() print data
1、urllib2.Request()的功能是構造一個請求資訊,返回的req就是一個構造好的請求。
通過Request()還可構造一些額外的請求資訊(metadata)。
2、urllib2.urlopen()的功能是發送剛剛構造好的請求req,並返回一個file類型的對象,r包括了所有的返回資訊。
3、通過r.read()可以讀取到r裡面的代碼,就是返回的頁面的原始碼。
# coding=utf-8import urllib2,urllibheaders = {'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'}url = 'http://blog.csdn.net/julius_lee/article/details/7682909'values = {'name': 'Michael Froord','location':'Northampton','language':'python'}data = urllib.urlencode(values)req = urllib2.Request(url,data,headers = headers)content = urllib2.urlopen(req).read()print content.decode('u8')
通過urllib2.Request()構造一個有額外資料的請求資訊。包括“http header”和想要發送的資料,這些資料需要被以標準的方式encode,然後作為一個資料參數傳送給Request對象。Encoding是在urllib中完成的,而不是在urllib2中完成的
urllib2中的核心類:
Request :一個具體的url請求,包含了請求的所有資訊,不僅僅試用於http協議
OpenerDirector:與BaseHandler組合,通過組合不同得handler處理不同的請求
BaseHandler :參與完成請求處理的類,不同的請求處理都繼承這個類
在urllib2中,一次請求被分為三個過程,分別是request,open,response
request:目的在於構造本次請求Request對象所需得所有資訊,如http協議中的header資訊
open:處理具體請求的過程,封裝Request對象,調用更底層的類完成請求並返回response
response:對返回的Response對象做處理
當然後有一個error處理的過程,但這個不是主動觸發的。
OpenerDirector
因為每次請求的具體實現是不同的handler,而且一次請求可能由很多handler組成。所以實現這一耦合機制的類就是OpenerDirector,這個類可以註冊(添加)各種不同的handler用來協助處理一次請求。通常來說handler中的命名規則為 protocol_request|open|response,這分別對應不同協議的三個過程。
Handler
urllib2提供很多handler來處理不同的請求,常用的HTTPHandler,FTPHandler都比較好理解。這裡提一下HTTPCookieProcessor和HTTPRedirectHandler
HTTPCookieProcessor是處理cookie的,在很多需要身分識別驗證的請求中cookie是必不可少的,python中對cookie的操作是有cookielib模組來完成的,而這個handler只是調用了其方法,在request和response過程中將cookie加到請求中和把cookie從響應中解析出來。
HTTPRedirectHandler是處理30x狀態的handler
Error handler
錯誤處理需要單獨講就是因為其特殊性,在urllib2中,處理錯誤的hanlder是HTTPErrorProcessor完成的
urlopen,install_opener,build_opener
這是urllib2模組的方法,在urllib2模組中存在一個全域變數儲存OpenerDirector執行個體。
urlopen方法則是調用了OpenerDirector執行個體的open方法
install_opener方法把一個OpenerDirector執行個體做為當前的opener
最關鍵的是build_opener,它決定了OpenerDirector中存在哪些handler