python爬虫-urllib模块
urllib 模塊是一個高級的 web 交流庫,其核心功能就是模仿web瀏覽器等客戶端,去請求相應(yīng)的資源,并返回一個類文件對象。urllib 支持各種 web 協(xié)議,例如:HTTP、FTP、Gopher;同時也支持對本地文件進(jìn)行訪問。但一般而言多用來進(jìn)行爬蟲的編寫,而下面的內(nèi)容也是圍繞著如何使用 urllib 庫去編寫簡單的爬蟲。另外,如果要爬取 js 動態(tài)生成的東西, 如 js 動態(tài)加載的圖片,還需要一些高級的技巧,這里的例子都是針對于靜態(tài)的 html 網(wǎng)頁的。
下面的說明都是針對于 python2.7 版本而言的,版本間存在差距,具體參考官方手冊。
首先,如果我需要寫一個爬蟲,去爬取一個網(wǎng)站的圖片的話,可以分為以下幾步:
當(dāng)然,你也可以將爬到的數(shù)據(jù)進(jìn)行各種處理分析,例如你可以寫一個比價網(wǎng)站,去各種網(wǎng)站獲取報價,然后整合到一起。所以,將上面的布置拓展到所有的爬蟲后:
下面我們按照這個通用的布置,學(xué)習(xí)每一步都應(yīng)該怎么做。
?
1.打開目標(biāo)網(wǎng)站
?urllib.urlopen(url[, data[, proxies[, context]]])?
去遠(yuǎn)程請求響應(yīng)的 url,并返回一個類文件對象。(注意,此處已經(jīng)發(fā)起了遠(yuǎn)程請求,也就是進(jìn)行了聯(lián)網(wǎng)操作,有數(shù)量流量)
url :? 一個完整的遠(yuǎn)程資源路徑,一般是一個網(wǎng)站。(注意,要包含協(xié)議頭,例如:http://www.baidu.com/,此處的 http:// 不能省略)
如果該URL沒有指明協(xié)議類型,或者其協(xié)議標(biāo)識符為file:,則該函數(shù)會打開本地文件。如果無法打開遠(yuǎn)程地址,將觸發(fā) IOError 異常。
data : 如果使用的是 http:// 協(xié)議,這是一個可選的參數(shù),用于指定一個 POST 請求(默認(rèn)使用的是 GET 方法)。這個參數(shù)必須使用標(biāo)準(zhǔn)的 application/x-www-form-urlencoded 格式。我們可以使用 ?urlencode() 方法來快速生成。
proxies : 設(shè)置代理,有需要的參照官方文檔。下面給出官網(wǎng)的例子:
# Use http://www.someproxy.com:3128 for HTTP proxying proxies = {'http': 'http://www.someproxy.com:3128'} filehandle = urllib.urlopen(some_url, proxies=proxies) # Don't use any proxies filehandle = urllib.urlopen(some_url, proxies={}) # Use proxies from environment - both versions are equivalent filehandle = urllib.urlopen(some_url, proxies=None) filehandle = urllib.urlopen(some_url)?
context :? 在用 HTTPS 連接時,這個參數(shù)要設(shè)置為? ssl.SSLContext 的實例,用于配置 SSL 。
一般而言,我們只需要設(shè)置 url 參數(shù)就可以了。
例如:
f = urllib.urlopen('http://www.baidu.com/')?
這樣我能就能夠得到一個類文件對象了,然后就可以對這個類文件對象進(jìn)行各種讀取操作了。
?
2.操作類文件對象
下面的方法和文件操作中的一致,下面列舉出來,詳情請參考我在python文件操作中的解釋:
1. read([size]) -> read at most size bytes, returned as a string.?
讀取整個文件,將讀取結(jié)果返回一個字符串對象
2.?readline([size]) -> next line from the file, as a string.?
讀取一行,將讀取結(jié)果返回一個字符串對象
3. readlines([size]) -> list of strings, each a line from the file.?
讀取整個文件,將每一行封裝成列表中的元素,返回一個列表。
4.?readinto() -> Undocumented. Don't use this; it may go away.?
一個可以無視的將要廢棄的方法
5.?close() -> None or (perhaps) an integer. Close the file.?
關(guān)閉文件,返回None或者一個表示關(guān)閉狀態(tài)的整數(shù)。
?
另外:也可以和文件對象一樣直接進(jìn)行迭代操作。
除了以上和文件操作中用法一樣的方法之外,還有以下特殊的方法:
1.?info()?
返回文件信息,對于 http 協(xié)議來說,返回的是響應(yīng)報文中的報文頭。
例子:
f = urllib.urlopen('http://www.so.com/') print f.info()?
?
2.?geturl()?
返回當(dāng)前頁面的真正的 url ,針對于網(wǎng)站服務(wù)器在進(jìn)行重定向以后,我們可以用它來獲取重定向后的頁面。
?
3.?getcode()?
返回當(dāng)前請求的狀態(tài)碼,如成功請求的狀態(tài)碼就是 200 。如果不是使用 http 協(xié)議打開的,就返回 None。
?
?
3.操作讀取后的網(wǎng)頁源碼
這個部分就和文件操作一樣了,但多數(shù)情況下會和 re 模塊配合起來進(jìn)行數(shù)據(jù)篩選,例如:
f = urllib.urlopen('http://www.baidu.com/') b = f.read() p = re.compile(r'<img.*?src="//(.*?\.(?:jpg|gif|png))".*?>', re.I) result = p.findall(b) print result?
嘗試在百度的首頁爬取圖片的地址,當(dāng)然還有很多改進(jìn)的地方,這里中做演示用。
關(guān)于python中的正則 re 模塊的使用這里就不再重復(fù)了。
?
?
4.下載相應(yīng)資源
在我們通過正則篩選出我們相要的圖片的 url 之后,就可以開始下載了,在 urllib 中提供了相應(yīng)的下載函數(shù)。
1.?urllib.urlretrieve(url[, filename[, reporthook[, data]]])?
將給定的 url 下載為本地文件,如果 url 指向的是本地的文件,或者是一個有效的緩存對象,那么將不會下載(注意,這里的存在是指下載的目錄里有相同的文件了)。返回一個元祖(filename, headers),其中filename值的是本地保存的文件名,header指的是上面 info() 方法返回的對象。
url : 目標(biāo) url 。
filename : 下載到本地后保存的文件名, 可以是決對路徑或相對路徑形式。如果沒有給,將緩存到一個臨時文件夾中。
reporthook:一個回調(diào)函數(shù),方法會在連接建立時和下載完成時調(diào)用這個函數(shù)。同時會向函數(shù)傳遞三個參數(shù):1.目前為止下載了多少數(shù)據(jù)塊;2.數(shù)據(jù)塊的大小(單位是字節(jié));3.文件的總大小;
data:如果使用的是 http:// 協(xié)議,這是一個可選的參數(shù),用于指定一個 POST 請求(默認(rèn)使用的是 GET 方法)。這個參數(shù)必須使用標(biāo)準(zhǔn)的 application/x-www-form-urlencoded 格式。我們可以使用?urlencode()來快速生成。
?
2.?urllib.urlcleanup()?
Clear the cache that may have been built up by previous calls to urlretrieve().
清除先前由 urlretrieve() 建立的緩存。
?
?
其他常用模塊內(nèi)置方法:
1.?urllib.quote(string[, safe])?
將 string 編碼成 url 格式,safe 指定不受影響的字符(默認(rèn) safe='/')。
因為 url 的編碼和我們常用的 ASCII 并不同,例如我們常用的空格在 ASCII 中:?'scolia good' 直接現(xiàn)實一個空白字符,而在 url 中:?'scolia%20good' ,原本的空白字符變成了 %20 。
其轉(zhuǎn)換規(guī)則為:
逗號,下劃線,句號,斜線和字母數(shù)字這類符號是不需要轉(zhuǎn)化。其他的則均需要轉(zhuǎn)換。另外, 那些不被允許的字符前邊會被加上百分號(%)同時轉(zhuǎn)換成 16 進(jìn)制,例如:“%xx”,“xx”代表這個字母的 ASCII 碼的十六進(jìn)制值。
例子:
f = urllib.quote('scolia good') print f?
?
2.?urllib.quote_plus(string[, safe])?
和上面的幾乎一樣,只是不轉(zhuǎn)換空白字符,而將其用 + 號替換。
例子:
f = urllib.quote_plus('scolia good') print f?
?
3.?urllib.unquote(string)?
將 url 重新轉(zhuǎn)碼回去,是上面操作的urllib.quote(string[, safe])逆運算。
4.?unquote_plus(string)?
同上,是urllib.quote_plus(string[, safe])的逆運算。
?
5.?urllib.urlencode(query[, doseq])?
? 將一個python的字典快速轉(zhuǎn)換為一個請求的格式,用于上面的 data 屬性。
例子:
aDict = {'name': 'Georgina Garcia', 'hmdir': '~ggarcia'} print urllib.urlencode(aDict)?
這里注意:一旦設(shè)置的 data,就意味使用 POST 請求,如果要使用 GET 請求,請在 url 的后面加上 ? 號,再將轉(zhuǎn)換好的數(shù)據(jù)放進(jìn)去。
例如:
GET方法:
import urllib 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方法:
import urllib params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0}) f = urllib.urlopen("http://www.musi-cal.com/cgi-bin/query", params) print f.read()?
6.?urllib.pathname2url(path)?
將本地路徑名轉(zhuǎn)換成 url 風(fēng)格的路徑名,這不會產(chǎn)生一個完整的URL,而且得到的結(jié)果已經(jīng)調(diào)用了 quote() 方法進(jìn)行了處理。
例子:
?
7.?urllib.url2pathname(path)?
將 url 風(fēng)格的路徑轉(zhuǎn)換為本地路徑風(fēng)格,是上面方法的逆運算。
a = r'www.xxx.com/12%203/321/' print urllib.url2pathname(a)?
同樣的調(diào)用了 quote() 方法進(jìn)行了處理
?
?
?
其他的內(nèi)容請參考官方文檔:https://docs.python.org/2/library/urllib.html
?
轉(zhuǎn)載于:https://www.cnblogs.com/scolia/p/5566554.html
總結(jié)
以上是生活随笔為你收集整理的python爬虫-urllib模块的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算广告概述【计算广告】
- 下一篇: 1 张图秒懂 Nova 16 种操作 -