來罐韩,讓我們寫一個網(wǎng)絡爬蟲,下載頁面上所有的照片吧污朽!

什么是網(wǎng)絡爬蟲散吵?

網(wǎng)絡爬蟲是一種非常有意思的程序。偌大的Internet蟆肆,就像是一只蜘蛛織成的大網(wǎng):一個個超級鏈接就是蛛絲矾睦,將無數(shù)頁面連接起來,而網(wǎng)絡爬蟲炎功,則會沿著一根根蛛絲枚冗,爬遍每一個節(jié)點……

網(wǎng)絡爬蟲

網(wǎng)絡爬蟲能干嘛?

蜘蛛在網(wǎng)上爬來爬去蛇损,當然不是為了健身赁温。它會在網(wǎng)上尋覓獵物,捕捉它們淤齐,并拖回自己的窩里股囊。

舉一個例子:某天某日的清晨,老板突然讓你將雪球網(wǎng)上所有的A股行情信息全部保存到一個Excel文件里床玻,以便他瀏覽毁涉。你點開了網(wǎng)址雪球(A股行情),驚喜地發(fā)現(xiàn)有三十四頁锈死,一條一條復制贫堰,顯然又累又笨穆壕,但是老板要看,你又不得不從其屏,惆悵啊……

很多時候喇勋,我們會需要做這樣的工作:將某一類型的文檔全部下載保存下來,然后進行分析偎行。一個一個點擊鼠標川背,顯然不現(xiàn)實。那么蛤袒,就做一個網(wǎng)絡爬蟲吧熄云,自動化地把需要的東西保存下來。

網(wǎng)絡爬蟲是怎么干的妙真?

一個簡單的網(wǎng)絡爬蟲的邏輯并不復雜缴允,就是模仿人類瀏覽網(wǎng)頁的動作:輸入網(wǎng)址,進入頁面珍德,瀏覽網(wǎng)頁练般,點擊鏈接,進入下一頁面……周而復始锈候。

當然薄料,嘴上說是這樣,還得要將步驟細化一下泵琳。所以先來看看瀏覽網(wǎng)頁的時候摄职,我們做了些什么。

當我們?yōu)g覽網(wǎng)頁的時候虑稼,瀏覽器在做些什么琳钉?

蒂姆·伯納斯-李在發(fā)明互聯(lián)網(wǎng)的時候势木,為了解決頁面之間相互連接的問題蛛倦,讓網(wǎng)絡瀏覽更加方便,發(fā)明了超文本標記語言HTML啦桌。它是一個文本文檔溯壶,但是文檔中會有一些特殊的標記——標簽,它可以標記出哪些位置的信息是標題甫男,哪些位置的信息是文本且改,哪些地方是圖像,哪些地方是超級鏈接板驳。它就長這樣又跛。

HTML

尖括號中間的就是標簽,里面的字就是標簽的名字若治,帶斜杠的表示標記結束了慨蓝。比如感混,<p>的意思是段落,</p>的意思就是這一段結束了礼烈。

瀏覽器可以根據(jù)標簽弧满,將網(wǎng)頁依照代碼的意思表現(xiàn)出來身诺,用點兒術語的話喉童,就是瀏覽器是一個HTML的解釋器。當我們?yōu)g覽網(wǎng)頁的時候钢颂,瀏覽器會先將網(wǎng)頁的HTML文件犀忱,以及所需要的其它元素都下載到你的電腦里募谎,然后根據(jù)HTML文件的內(nèi)容,將網(wǎng)頁展現(xiàn)在你的面前阴汇。

所以網(wǎng)絡爬蟲也需要干這件事情:下載HTML文件近哟,然后分析它,根據(jù)分析的結果將需要的文本或者圖像什么的下載下來鲫寄,找到超級鏈接吉执,繼續(xù)……

讓我們寫一個網(wǎng)絡爬蟲,下載頁面上所有的照片吧地来!

知乎上有很多提問戳玫,下面會有很多照片,比如這個怎么用手機拍出精彩的照片未斑?咕宿,圖片都挺好看的,我想全部下載下來蜡秽,怎么辦呢府阀?打開頁面以后,右鍵點擊頁面芽突,選擇【查看源文件】试浙,就可以看到HTML文件的內(nèi)容了。簡單分析一下寞蚌,會發(fā)現(xiàn)照片其實都在這樣的標簽下面:

img標簽

所以田巴,現(xiàn)在就可以制定出我們的策略了:打開頁面,分析它的HTML源文件挟秤,找出所有img標簽壹哺,將里面的圖片都保存下來,over艘刚!

用Python實現(xiàn)你的第一個網(wǎng)絡爬蟲

Python語言語法簡單而靈活管宵,實用的庫(別人寫好,可以直接實用的代碼)非常多,很適合寫這種小爬蟲箩朴。所以我們用Python來寫一個網(wǎng)絡爬蟲笛臣。可以點擊這里下載Python環(huán)境的安裝包隧饼,一直下一步就可以安裝好了沈堡。具體學習Python可以看這本書,或者這本書燕雁。這里我們的代碼并不復雜诞丽,需要的知識點不多,我會一點一點講解的拐格。當然你可能需要一點點程序設計的知識僧免。

在一個文本編輯器里面輸入以下代碼:

#-*-coding:utf-8-*-

import urllib

url = "https://www.zhihu.com/question/20922273"

page = urllib.urlopen(url)

print page.read()

找一個文件夾,保存為example1.py捏浊。然后點擊右鍵選擇【EDIT with IDLE】懂衩。

打開以后按F5鍵。應該會出現(xiàn)這樣的窗口金踪。

是不是打印出了原來頁面的HTML文件的內(nèi)容浊洞?

下面來解釋一下這一段代碼的意思。

#-*-coding:utf-8-*- 的意思是這一段Python程序的編碼格式是UTF-8胡岔。理解這一點需要一些編碼的知識法希,這里暫時不用管它。一般每一個Python程序第一句話都是這個靶瘸。

import urllib 的意思是導入urllib庫苫亦,python自帶的一個網(wǎng)絡庫,我們可以用它來實現(xiàn)訪問網(wǎng)頁怨咪,下載文件等功能屋剑。當然還有很多功能更高級的庫,比如urllib2或者requests等诗眨,這里我們挑一個簡單的先唉匾。

url = "https://www.zhihu.com/question/20922273" 這句話的意思是定義url為字符串"https://www.zhihu.com/question/20922273" ,也就是我們要訪問的網(wǎng)頁的網(wǎng)址辽话,可以看出肄鸽,網(wǎng)址實際上是一個字符串變量卫病。

page = urllib.urlopen(url) 這句話的意思是使用urllib庫里面的urlopen函數(shù)油啤,打開網(wǎng)址url,并把打開的這個對象命名為page(打開了一個東西蟀苛,雖然我們不知道它是什么益咬,但是先給它起個名字吧!)帜平。

page.read() 的意思就是讀取page這個對象的內(nèi)容幽告。print page.read()的意思自然就是打印這個內(nèi)容了梅鹦。

于是,我們就完成了第一步冗锁,打開頁面齐唆。下面,我們來寫程序分析打開的頁面冻河。

寫程序箍邮,找出所有的圖片地址

在IDLE里面,把前面寫的代碼改一改叨叙。

#-*-coding:utf-8-*-

import urllib

from sgmllib import SGMLParser

class ZhihuParser(SGMLParser):

imgList = []

def reset(self):

? ? SGMLParser.reset(self)? #初始化

? ? self.imgList = []

? ? def start_img(self, attrs):

? ? imgUrl = [v for k, v in attrs if k=='data-original']

? ? if imgUrl:

? ? ? ? self.imgList.append(imgUrl[0])

? ? ? ? imgUrl = ""

? ? ? ? url = "https://www.zhihu.com/question/20922273"

? ? ? ? page = urllib.urlopen(url)

? ? ? ? parser = ZhihuParser()

? ? ? ? parser.feed(page.read())

? ? ? ? print parser.imgList

點擊F5運行锭弊,看看結果。


下面來解釋一下代碼擂错。

from sgmllib import SGMLParser 這一句的意思是從sgmllib文件里面導入SGMLParser這個包味滞。這個包是Python自帶的一個解析HTML的庫。

class ZhihuParser(SGMLParser):是定義一個類ZhihuParser钮呀,它繼承SGMLParser這個類剑鞍。我們對它進行一些修改。

imgList = [] 聲明了一個列表爽醋,我們用它來保存所有圖片的地址攒暇。

def reset(self): 這個函數(shù)是ZhihuParser類的初始化函數(shù)。每一次生成ZhihuParser類的對象的時候都會調(diào)用這個函數(shù)子房。我們讓這個函數(shù)先初始化SGMLParser.reset(self)形用,然后把列表制空self.imgList = []。

def start_img(self, attrs): 這個函數(shù)是解析img標簽的函數(shù)证杭。當SGMLParser遇到一個img標簽的時候田度,就會調(diào)用這個函數(shù)。比如我們要解析<a>標簽解愤,那就自己定義一個函數(shù)start_a,解析標簽镇饺,就定義一個函數(shù)start_head,函數(shù)的內(nèi)容是我們需要的動作送讲。對于這樣的結束標簽奸笤,對應的函數(shù)是end_something(self)。

start_something函數(shù)的參數(shù)是(self,attrs)哼鬓。self自然就是類本身监右,attrs是SGMLParser解析出來的標簽參數(shù),比如知乎img的代碼:

里面的src异希, data-rawwidth等等健盒,都是標簽的參數(shù),它以字典的形式傳入函數(shù)中,即一系列參數(shù)名:參數(shù)的二元對扣癣。這里我們需要提取出地址惰帽,即data-original的內(nèi)容,imgUrl = [v for k, v in attrs if k=='data-original']父虑,意思是遍歷attrs该酗,如果字典的名為data-original,就保存下來士嚎。

如果imgUrl保存成功垂涯,我們就把它導入到列表里,self.imgList.append(imgUrl[0])航邢。然后將臨時變量imgUrl制空(這句話其實不必要)耕赘。

parser = ZhihuParser()定義了一個ZhihuParser對象,parser.feed(page.read())將頁面的內(nèi)容傳入parser膳殷,進行解析操骡。print parser.imgList將所有的圖片地址打印出來。

下面我們繼續(xù)修改代碼赚窃,把所有圖片保存下來册招。

在上面的基礎上加入如下代碼:

cnt=1

for?url?in?parser.imgList:

? ? f=open("%d.jpg"%cnt,'wb')

? ? img=urllib.urlopen(url)

? ? f.write(img.read())

? ? f.close()

? ? print?"%d?was?done!"%cnt

? ? cnt?+=?1

cnt = 1是定義一個計數(shù)器,記錄我們下載圖片的個數(shù)勒极。

for url in parser.imgList:遍歷圖片地址列表是掰。

f = open("%d.jpg"%cnt,'wb')打開一個文件。我們將下載下來的圖片寫入這個文件中辱匿。

img = urllib.urlopen(url)打開圖片地址键痛。

f.write(img.read())將圖片寫入文件,然后關閉文件匾七。

運行程序絮短,不一會就看見我們將所有的網(wǎng)頁上的圖片都下載了下來。


于是乎昨忆,我們就完成了一個最簡單的網(wǎng)絡爬蟲丁频。

后 ? ?記

事實上,真正的通用網(wǎng)絡爬蟲是很難寫的邑贴,要考慮的因素很多席里。比如怎樣規(guī)避網(wǎng)站的反爬蟲機制(有的網(wǎng)站可不愿意你下載文件,占用帶寬)拢驾,怎樣避免爬蟲陷阱(比如有兩個頁面有相互連接的超級鏈接奖磁,于是爬蟲就會一直在這兩個頁面間爬來爬去,不去其他頁面)独旷,怎樣大規(guī)氖鹚耄快速地爬(分布式爬蟲)寥裂,怎樣解析JavaScript等等等等嵌洼。事實上案疲,網(wǎng)絡爬蟲是搜索引擎的核心技術之一,google麻养,百度等搜索引擎公司每天都不停地在網(wǎng)絡上爬取頁面褐啡,解析,并排序鳖昌,給我們提供搜索服務备畦。


PS:我不太懂怎么樣在簡書打代碼。许昨。懂盐。排版有點丑,請見諒糕档。歡迎來我的Csdn看看莉恼,剛開始寫,文章不多速那。我以后會在上面寫一些我的學習筆記俐银。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市端仰,隨后出現(xiàn)的幾起案子捶惜,更是在濱河造成了極大的恐慌,老刑警劉巖荔烧,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吱七,死亡現(xiàn)場離奇詭異,居然都是意外死亡鹤竭,警方通過查閱死者的電腦和手機陪捷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來诺擅,“玉大人市袖,你說我怎么就攤上這事∷赣浚” “怎么了苍碟?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長撮执。 經(jīng)常有香客問我微峰,道長,這世上最難降的妖魔是什么抒钱? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任蜓肆,我火速辦了婚禮颜凯,結果婚禮上,老公的妹妹穿的比我還像新娘仗扬。我一直安慰自己症概,他們只是感情好,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布早芭。 她就那樣靜靜地躺著彼城,像睡著了一般。 火紅的嫁衣襯著肌膚如雪退个。 梳的紋絲不亂的頭發(fā)上募壕,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機與錄音语盈,去河邊找鬼舱馅。 笑死,一個胖子當著我的面吹牛刀荒,可吹牛的內(nèi)容都是我干的代嗤。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼照棋,長吁一口氣:“原來是場噩夢啊……” “哼资溃!你這毒婦竟也來了?” 一聲冷哼從身側響起烈炭,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤溶锭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后符隙,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體趴捅,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年霹疫,在試婚紗的時候發(fā)現(xiàn)自己被綠了拱绑。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡丽蝎,死狀恐怖猎拨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情屠阻,我是刑警寧澤红省,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站国觉,受9級特大地震影響吧恃,放射性物質發(fā)生泄漏。R本人自食惡果不足惜麻诀,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一痕寓、第九天 我趴在偏房一處隱蔽的房頂上張望傲醉。 院中可真熱鬧,春花似錦呻率、人聲如沸硬毕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽昭殉。三九已至苞七,卻和暖如春藐守,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蹂风。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工卢厂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人惠啄。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓慎恒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親撵渡。 傳聞我的和親對象是個殘疾皇子融柬,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 1 前言 作為一名合格的數(shù)據(jù)分析師,其完整的技術知識體系必須貫穿數(shù)據(jù)獲取趋距、數(shù)據(jù)存儲粒氧、數(shù)據(jù)提取、數(shù)據(jù)分析节腐、數(shù)據(jù)挖掘外盯、...
    whenif閱讀 18,072評論 45 523
  • Python爬蟲入門(urllib+Beautifulsoup) 本文包括:1、爬蟲簡單介紹2翼雀、爬蟲架構三大模塊3...
    廖少少閱讀 9,833評論 0 6
  • 聲明:本文講解的實戰(zhàn)內(nèi)容饱苟,均僅用于學習交流,請勿用于任何商業(yè)用途狼渊! 一箱熬、前言 強烈建議:請在電腦的陪同下,閱讀本文...
    Bruce_Szh閱讀 12,704評論 6 28
  • 記得這樣一個電視畫面——孩子仰頭問爸爸:“什么是歷史狈邑?”爸爸微笑回答:“歷史就是過去的事情城须。” 自此官地,歷史的概念映...
    每文兒閱讀 685評論 10 9
  • 目錄 第20章:植物人嗎 第21章:能不能不看我 我低著頭看著他骨骼分明的手指酿傍,這么修長好看的手指我曾偷偷看過無數(shù)...
    九命貓兒閱讀 274評論 0 1