溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

手把手教你寫網(wǎng)絡爬蟲(2):迷你爬蟲架構(gòu)

發(fā)布時間:2020-06-25 22:24:06 來源:網(wǎng)絡 閱讀:1260 作者:Lickm 欄目:編程語言

介紹

大家好!回顧上一期,我們在介紹了爬蟲的基本概念之后,就利用各種工具橫沖直撞的完成了一個小爬蟲,目的就是猛、糙、快,方便初學者上手,建立信心。對于有一定基礎的讀者,請不要著急,以后我們會學習主流的開源框架,打造出一個強大專業(yè)的爬蟲系統(tǒng)!不過在此之前,要繼續(xù)打好基礎,本期我們先介紹爬蟲的種類,然后選取最典型的通用網(wǎng)絡爬蟲,為其設計一個迷你框架。有了自己對框架的思考后,再學習復雜的開源框架就有頭緒了。

今天我們會把更多的時間用在思考上,而不是一根筋的coding。用80%的時間思考,20%的時間敲鍵盤,這樣更有利于進步。

手把手教你寫網(wǎng)絡爬蟲(2):迷你爬蟲架構(gòu)


語言&環(huán)境

語言:帶足彈藥,繼續(xù)用Python開路!

手把手教你寫網(wǎng)絡爬蟲(2):迷你爬蟲架構(gòu)



threadingthreading庫可以在單獨的線程中執(zhí)行任何的在Python中可以調(diào)用的對象。Python 2.x中的thread模塊已被廢棄,用戶可以使用threading模塊代替。在Python 3中不能再使用thread模塊。為了兼容性,Python 3將thread重命名為_thread。


queuequeue模塊中提供了同步的、線程安全的隊列類,包括FIFO(先入先出)隊列Queue,LIFO(后入先出)隊列LifoQueue,和優(yōu)先級隊列PriorityQueue。這些隊列都實現(xiàn)了鎖原語,能夠在多線程中直接使用??梢允褂藐犃衼韺崿F(xiàn)線程間的同步。


rePython 自1.5版本起增加了re模塊,它提供Perl風格的正則表達式模式。re模塊使 Python語言擁有全部的正則表達式功能。


argparsePython用于解析命令行參數(shù)和選項的標準模塊,用于代替已經(jīng)過時的optparse模塊。argparse模塊的作用是用于解析命令行參數(shù)。


configparser讀取配置文件的模塊。


爬蟲的種類

手把手教你寫網(wǎng)絡爬蟲(2):迷你爬蟲架構(gòu)


網(wǎng)絡爬蟲按照系統(tǒng)結(jié)構(gòu)和實現(xiàn)技術(shù),大致可以分為以下幾種類型:通用網(wǎng)絡爬蟲(General Purpose Web Crawler)、聚焦網(wǎng)絡爬蟲(Focused Web Crawler)、增量式網(wǎng)絡爬蟲(Incremental Web Crawler)、深層網(wǎng)絡爬蟲(Deep Web Crawler)。實際的網(wǎng)絡爬蟲系統(tǒng)通常是幾種爬蟲技術(shù)相結(jié)合實現(xiàn)的。


通用網(wǎng)絡爬蟲

通用網(wǎng)絡爬蟲又稱全網(wǎng)爬蟲(Scalable Web Crawler),爬取對象從一些種子 URL 擴充到整個 Web。主要為門戶站點搜索引擎和大型 Web 服務提供商采集數(shù)據(jù)。

通用網(wǎng)絡爬蟲的結(jié)構(gòu)大致可以分為頁面爬取模塊 、頁面分析模塊、鏈接過濾模塊、頁面存儲模塊、URL 隊列、初始 URL 集合幾個部分。為提高工作效率,通用網(wǎng)絡爬蟲會采取一定的爬取策略。 常用的爬取策略有:深度優(yōu)先策略、廣度優(yōu)先策略。

1) 深度優(yōu)先策略(DFS):其基本方法是按照深度由低到高的順序,依次訪問下一級網(wǎng)頁鏈接,直到不能再深入為止。

2) 廣度優(yōu)先策略(BFS):此策略按照網(wǎng)頁內(nèi)容目錄層次深淺來爬取頁面,處于較淺目錄層次的頁面首先被爬取。 當同一層次中的頁面爬取完畢后,爬蟲再深入下一層繼續(xù)爬取。


聚焦網(wǎng)絡爬蟲

聚焦網(wǎng)絡爬蟲(Focused Crawler),又稱主題網(wǎng)絡爬蟲(Topical Crawler),是指選擇性地爬取那些與預先定義好的主題相關頁面的網(wǎng)絡爬蟲。 和通用網(wǎng)絡爬蟲相比,聚焦爬蟲只需要爬取與主題相關的頁面,極大地節(jié)省了硬件和網(wǎng)絡資源,保存的頁面也由于數(shù)量少而更新快,還可以很好地滿足一些特定人群對特定領域信息的需求。我們之前爬的歌單就屬于這一種。


增量式網(wǎng)絡爬蟲

增量式網(wǎng)絡爬蟲(Incremental Web Crawler)是 指 對 已 下 載 網(wǎng) 頁 采 取 增 量式更新和只爬取新產(chǎn)生的或者已經(jīng)發(fā)生變化網(wǎng)頁的爬蟲,它能夠在一定程度上保證所爬取的頁面是盡可能新的頁面。 和周期性爬取和刷新頁面的網(wǎng)絡爬蟲相比,增量式爬蟲只會在需要的時候爬取新產(chǎn)生或發(fā)生更新的頁面 ,并不重新下載沒有發(fā)生變化的頁面,可有效減少數(shù)據(jù)下載量,及時更新已爬取的網(wǎng)頁,減小時間和空間上的耗費,但是增加了爬取算法的復雜度和實現(xiàn)難度。現(xiàn)在比較火的輿情爬蟲一般都是增量式網(wǎng)絡爬蟲。


深網(wǎng)爬蟲

Web 頁面按存在方式可以分為表層網(wǎng)頁(Surface Web)和深層網(wǎng)頁(Deep Web,也稱 Invisible Web Pages 或 Hidden Web)。 表層網(wǎng)頁是指傳統(tǒng)搜索引擎可以索引的頁面,以超鏈接可以到達的靜態(tài)網(wǎng)頁為主構(gòu)成的 Web 頁面。Deep Web 是那些大部分內(nèi)容不能通過靜態(tài)鏈接獲取的、隱藏在搜索表單后的,只有用戶提交一些關鍵詞才能獲得的 Web 頁面。例如那些用戶注冊后內(nèi)容才可見的網(wǎng)頁就屬于 Deep Web。


一個迷你框架

下面以比較典型的通用爬蟲為例,分析其工程要點,設計并實現(xiàn)一個迷你框架。架構(gòu)圖如下:

手把手教你寫網(wǎng)絡爬蟲(2):迷你爬蟲架構(gòu)

代碼結(jié)構(gòu):

手把手教你寫網(wǎng)絡爬蟲(2):迷你爬蟲架構(gòu)


config_load.py    配置文件加載

crawl_thread.py    爬取線程

mini_spider.py    主線程

spider.conf    配置文件

url_table.py    url隊列、url表

urls.txt    種子url集合

webpage_parse.py    網(wǎng)頁分析

webpage_save.py    網(wǎng)頁存儲


看看配置文件里有什么內(nèi)容:

spider.conf

手把手教你寫網(wǎng)絡爬蟲(2):迷你爬蟲架構(gòu)


Step 1. 采用BFS還是DFS?

理論上,這兩個算法都能夠在大致相同的時間里爬取整個互聯(lián)網(wǎng)上的內(nèi)容。但顯然各個網(wǎng)站最重要的網(wǎng)頁應該是它的首頁。在極端情況下,如果只能下載非常有限的網(wǎng)頁,那么應該下載的所有網(wǎng)站的首頁,如果把爬蟲再擴大些,應該爬取從首頁直接鏈接的網(wǎng)頁,因為這些網(wǎng)頁是網(wǎng)站設計者自己認為相當重要的網(wǎng)頁。在這個前提下,顯然BFS明顯優(yōu)于DFS。事實上在搜索引擎的爬蟲里,主要采用的就是BFS。我們的框架采取這種策略。

抓取深度可以通過配置文件中的max_depth設置,只要沒到達指定深度,程序就會不停的將解析出的url放入隊列中:

mini_spider.py

手把手教你寫網(wǎng)絡爬蟲(2):迷你爬蟲架構(gòu)


Step 2. 初始URL集合、URL隊列

我們來看看通用爬蟲如何下載整個互聯(lián)網(wǎng)。假設從一家門戶網(wǎng)站的首頁出發(fā),先下載這個網(wǎng)頁(深度=0),然后通過分析這個網(wǎng)頁,可以找到頁面里的所有超鏈接,也就等于知道了這家門戶網(wǎng)站首頁所直接連接的全部網(wǎng)頁,諸如京東理財、京東白條,京東眾籌等(深度=1)。接下來訪問、下載并分析京東理財?shù)染W(wǎng)頁,又能找到其他相連的網(wǎng)頁(深度=2)。讓計算機不停的做下去,就能下載整個網(wǎng)站。

在這個過程中,我們需要一個“初始URL集合”保存門戶的首頁,還需要一個“URL隊列”保存分析網(wǎng)頁得到的超鏈接。

mini_spider.py

手把手教你寫網(wǎng)絡爬蟲(2):迷你爬蟲架構(gòu)


url_table.py

手把手教你寫網(wǎng)絡爬蟲(2):迷你爬蟲架構(gòu)


Step 3. 記錄哪些網(wǎng)頁已經(jīng)下載過的小本本——URL表。

在互聯(lián)網(wǎng)上,一個網(wǎng)頁可能被多個網(wǎng)頁中的超鏈接所指向。這樣在遍歷互聯(lián)網(wǎng)這張圖的時候,這個網(wǎng)頁可能被多次訪問到。為了防止一個網(wǎng)頁被下載和解析多次,需要一個URL表記錄哪些網(wǎng)頁已經(jīng)下載過。再遇到這個網(wǎng)頁的時候,我們就可以跳過它。

crawl_thread.py

手把手教你寫網(wǎng)絡爬蟲(2):迷你爬蟲架構(gòu)


Step 4. 多個抓取線程

為了提升爬蟲性能,需要多個抓取線程,從URL隊列獲取鏈接進行處理。多線程并沒什么毛病,但Python的多線程可能會引起很多人的質(zhì)疑,這源于Python設計之初的考慮:GIL。GIL的全稱是Global Interpreter Lock(全局解釋器鎖),某個線程想要執(zhí)行,必須先拿到GIL,并且在一個Python進程中,GIL只有一個。結(jié)果就是Python里一個進程永遠只能同時執(zhí)行一個線程,這就是為什么在多核CPU上,Python的多線程效率并不高。那么我們?yōu)槭裁催€要用Python多線程呢?

CPU密集型代碼(各種循環(huán)處理、編解碼等等),在這種情況下,由于計算工作多,ticks計數(shù)很快就會達到閾值,然后觸發(fā)GIL的釋放與再競爭(多個線程來回切換當然是需要消耗資源的),Python下的多線程對CPU密集型代碼并不友好。

IO密集型代碼(文件處理、網(wǎng)絡爬蟲等),多線程能夠有效提升效率(單線程下有IO操作會進行IO等待,造成不必要的時間浪費,而開啟多線程能在線程A等待時,自動切換到線程B,可以不浪費CPU的資源,從而能提升程序執(zhí)行效率)。Python的多線程對IO密集型代碼比較友好。

所以,對于IO密集的爬蟲程序,使用Python多線程是沒問題的。

crawl_thread.py

手把手教你寫網(wǎng)絡爬蟲(2):迷你爬蟲架構(gòu)


Step 5. 頁面分析模塊

從網(wǎng)頁中解析出URLs或者其他有用的數(shù)據(jù)。這個是上期重點介紹的,可以參考之前的代碼。


Step 6. 頁面存儲模塊

保存頁面的模塊,目前將文件保存為文件,以后可以擴展出多種存儲方式,如mysqlmongodb,hbase等等。

webpage_save.py

手把手教你寫網(wǎng)絡爬蟲(2):迷你爬蟲架構(gòu)


寫到這里,整個框架已經(jīng)清晰的呈現(xiàn)在大家眼前了,千萬不要小看它,不管多么復雜的框架都是在這些基本要素上擴展出來的。


下一步

基礎知識的學習暫時告一段落,希望能夠幫助大家打下一定的基礎。下期開始為大家介紹強大成熟的爬蟲框架Scrapy,它提供了很多強大的特性來使得爬取更為簡單高效,更多精彩,敬請期待!

最后,初學者進階的福音

想學習,基礎不夠?沒關系,我們提供免費提供VIP基礎學習課程,讓你快速入門,掌握Python!

 

有基礎的小伙伴想學習項目實戰(zhàn)?沒問題,每晚八點都有博士大牛帶你學習操作項目!

 

只要你有一顆想學習的心,我們隨時歡迎~


手把手教你寫網(wǎng)絡爬蟲(2):迷你爬蟲架構(gòu)




向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI