周毅 李威 何金 程蕾 柳璐
摘? 要:針對傳統(tǒng)單機(jī)網(wǎng)絡(luò)爬蟲抓取效率低、穩(wěn)定性差、數(shù)據(jù)量少等問題,文章利用Scrapy框架結(jié)合Redis技術(shù),對傳統(tǒng)網(wǎng)絡(luò)爬蟲框架進(jìn)行改進(jìn)和優(yōu)化,設(shè)計出了分布式非結(jié)構(gòu)化的網(wǎng)絡(luò)爬蟲系統(tǒng),使采集到的信息能以非結(jié)構(gòu)化形式存儲于MongoDB數(shù)據(jù)庫內(nèi),實(shí)現(xiàn)對數(shù)據(jù)信息的實(shí)時、有效處理分析。經(jīng)過實(shí)際應(yīng)用測試,證明基于Scrapy框架的分布式非結(jié)構(gòu)化網(wǎng)絡(luò)爬蟲系統(tǒng)相較于傳統(tǒng)單機(jī)系統(tǒng)具有更高的效率。
關(guān)鍵詞:分布式;Scrapy框架;網(wǎng)絡(luò)爬蟲
中圖分類號:TP311? ? ? ? ? ? ? ? ?文獻(xiàn)標(biāo)識碼:A文章編號:2096-4706(2021)19-0043-04
Design and Implementation of Distributed Web Crawler System Based
On Scrapy Framework
ZHOU Yi, LI Wei, HE Jin, CHENG Lei, LIU Lu
(Information and Communication Branch of State Grid Liaoning Electric Power Supply Co., Ltd., Shenyang? 110055, China)
Abstract:Aiming at the problems of low capture efficiency, poor stability and small amount of data on traditional single-machine web crawler, this paper uses Scrapy framework and Redis technology to improve and optimize the traditional web crawler framework, and designs a distributed and unstructured web crawler system, which enables the collected information to be stored in the MongoDB database in an unstructured form, so as to achieve real-time and effective processing and analysis of data information. After practical application test, it is proved that the distributed and unstructured web crawler system based on Scrapy framework has higher efficiency than the traditional single-machine system.
Keywords: distributed; Scripy framework; Web crawler
0? 引? 言
隨著大數(shù)據(jù)時代的到來,人們對數(shù)據(jù)的需求與日俱增。為了對萬維網(wǎng)上的數(shù)據(jù)進(jìn)行特定的搜索,各種搜索引擎也是層出不窮,搜索引擎在數(shù)據(jù)搜集中站著越來越重要的地位,但正是因為信息的高速發(fā)展,用戶對信息的搜索也是越來越嚴(yán)苛,如今的搜索引擎也越來越難以滿足用戶的需求[1]。因此,互聯(lián)網(wǎng)數(shù)據(jù)的搜集成為當(dāng)代科技必不可少的技術(shù)之一,網(wǎng)絡(luò)爬蟲技術(shù)應(yīng)運(yùn)而生。網(wǎng)絡(luò)爬蟲技術(shù)能夠?qū)崿F(xiàn)互聯(lián)網(wǎng)信息的自動化搜集,并將相關(guān)信息存入數(shù)據(jù)庫內(nèi)部。但傳統(tǒng)單機(jī)網(wǎng)絡(luò)爬蟲抓取效率低、穩(wěn)定性差、數(shù)據(jù)量少,不能滿足大數(shù)據(jù)時代下的數(shù)據(jù)需求;針對開源爬蟲方面,雖然已研發(fā)出Nutch、Larbin等網(wǎng)絡(luò)爬蟲項目,但普遍存在運(yùn)行效率低、穩(wěn)定性差、不支持中文等問題。因此本文提出基于Scrapy框架的分布式網(wǎng)絡(luò)爬蟲系統(tǒng)。
1? 相關(guān)原理與技術(shù)
1.1? 網(wǎng)絡(luò)爬蟲
網(wǎng)絡(luò)爬蟲(Web Crawler),又稱為網(wǎng)絡(luò)蜘蛛(Web Spider)或Web信息采集器,是一個自動下載網(wǎng)頁的計算機(jī)程序或自動化腳本,是搜索引擎的重要組成部分[2]。網(wǎng)絡(luò)爬蟲通常從一個預(yù)先設(shè)定好的URL集合開始運(yùn)行,首先將所有URL有序或隨機(jī)地放入到一個有序的待爬行隊列里;然后按照隊列順序,從隊列中取出URL并對URL地址發(fā)起網(wǎng)絡(luò)請求,得到網(wǎng)頁內(nèi)容,分析頁面內(nèi)容;再提取新的URL按先后順序存入待爬行隊列中,循環(huán)整個過程,直到待爬行隊列為空或滿足預(yù)設(shè)的爬行終止條件。該過程稱為網(wǎng)絡(luò)爬行(Web Crawling),網(wǎng)絡(luò)爬蟲根據(jù)設(shè)計需求和技術(shù)實(shí)現(xiàn),大致可以分為以下幾種類型:通用網(wǎng)絡(luò)爬蟲(General Purpose Web Crawler)、聚焦網(wǎng)絡(luò)爬蟲(Focused Web Crawler)、增量式網(wǎng)絡(luò)爬蟲(Incremental Web Crawler)、深層網(wǎng)絡(luò)爬蟲(Deep Web Crawler)[3]。在實(shí)際使用場景中,通常是幾種爬蟲技術(shù)相結(jié)合實(shí)現(xiàn)的。為了提高爬行效率,通常會采取多點(diǎn)并行的設(shè)計架構(gòu),但需要在爬行過程中解決重復(fù)性(并行運(yùn)行過程中,可能會產(chǎn)生重復(fù)URL)、爬行質(zhì)量(并行運(yùn)行過程中,每次爬取動作可能只獲取部分頁面,導(dǎo)致抓取到的數(shù)據(jù)不完善)。網(wǎng)絡(luò)爬蟲有很多使用場景,搜索引擎用通過網(wǎng)絡(luò)爬蟲來建立網(wǎng)頁索引,實(shí)現(xiàn)網(wǎng)絡(luò)資源的快速搜索;在進(jìn)行網(wǎng)站維護(hù)時,網(wǎng)絡(luò)爬蟲用于檢查網(wǎng)站鏈接是否有效、源碼是否篡改等。
1.2? 網(wǎng)絡(luò)爬蟲框架Scrapy
Scrapy框架是一個用于結(jié)構(gòu)化、模式化提取網(wǎng)絡(luò)資源的應(yīng)用框架。最初是為了抓取網(wǎng)站數(shù)據(jù)而設(shè)計的,也可以用于在獲取API接口的數(shù)據(jù)(各類網(wǎng)站數(shù)據(jù)接口等)或者構(gòu)造通用網(wǎng)絡(luò)爬蟲系統(tǒng)。Scrapy用途廣泛,可以用于數(shù)據(jù)挖掘、監(jiān)測和自動化測試[4]。Scrapy框架通過Twisted異步網(wǎng)絡(luò)庫來處理網(wǎng)絡(luò)通訊,實(shí)現(xiàn)網(wǎng)絡(luò)爬蟲的異步化。
Scrapy框架主要包括以下組件:Scrapy Engine(引擎);Spider Middlewares(蜘蛛中間件);Spiders(蜘蛛);Scheduler(Middlewares調(diào)度中間件);Scheduler(調(diào)度器);Downloader Middlewares(下載器中間件);Downloader(下載器);Item Pipeline(項目管道)。
1.3? Xpath頁面解析
Xpath全稱XMLpathLanguage,即XML路徑語言,它是一種用來確定XML文檔中某部分位置的語言,也適用于HTML文檔的定位和搜索。在分析網(wǎng)頁內(nèi)容時,主要有三種提取網(wǎng)頁數(shù)據(jù)的方式:正則表達(dá)式、BeautifulSoup庫和Xpath。Xpath頁面解析主要有以下特點(diǎn):提供了簡潔明了的路徑選擇表達(dá)式,高效實(shí)現(xiàn)對字符串、時間等字段的匹配能力;Xpath的路徑選擇表達(dá)式能實(shí)現(xiàn)網(wǎng)頁內(nèi)容的序列化處理,能夠迅速定位網(wǎng)頁的標(biāo)簽節(jié)點(diǎn);Xpath比BeautifulSoup運(yùn)行效率高、比正則表達(dá)式使用方便。因此本文使用Xpath對頁面進(jìn)行解析。
1.4? Scrapy-Redis技術(shù)
Redis是一種使用c語言編寫的,支持網(wǎng)絡(luò),可基于內(nèi)存亦可持久化的日執(zhí)行并提供多種語言的Nosql數(shù)據(jù)庫。在Scrapy-Redis中存放了待爬取的request對象以及已被獲取的request對象指紋,基于Redis 緩存數(shù)據(jù)庫,我們可以實(shí)現(xiàn)分布式的增量式爬蟲。當(dāng)獲取到一個request對象時,首先將該對象生成指紋,與緩存數(shù)據(jù)庫中的指紋相比較,若存在相同的指紋,表示該request對象已經(jīng)被另外一臺服務(wù)器請求過,不需要再次存入緩存數(shù)據(jù)庫中,如不存在相同的指紋,則將該request對象放入數(shù)據(jù)庫中并且生成指紋存入數(shù)據(jù)庫中,這樣就可以通過redis實(shí)現(xiàn)多臺服務(wù)器的分布式爬蟲。當(dāng)一臺服務(wù)器停止爬蟲再重新開始爬蟲時,由于之前的request對象已經(jīng)存入緩存數(shù)據(jù)庫中,再重新爬蟲時,從redis中讀取request對象時,仍然從上次停止的地方開始爬取,這就實(shí)現(xiàn)了斷點(diǎn)續(xù)爬的功能,也就是增量式的爬蟲[5]。
2? 系統(tǒng)設(shè)計與實(shí)現(xiàn)
基于Scrapy框架的分布式網(wǎng)絡(luò)爬蟲系統(tǒng)架構(gòu)分為數(shù)據(jù)層和業(yè)務(wù)層:數(shù)據(jù)層采用Scrapy爬蟲框架,負(fù)責(zé)信息數(shù)據(jù)的獲取和爬蟲系統(tǒng)調(diào)度的工作。通過繼承并重寫Spiders類,實(shí)現(xiàn)定制化爬蟲功能。數(shù)據(jù)層最終將數(shù)據(jù)存入MongoDB集群中,為業(yè)務(wù)層提供數(shù)據(jù)源。業(yè)務(wù)層采用Node.js框架技術(shù),用Server類實(shí)現(xiàn)服務(wù)器收發(fā)請求功能,并提供正向和逆向的Ajax交互[6]。
2.1? 數(shù)據(jù)層設(shè)計與實(shí)現(xiàn)
數(shù)據(jù)層,負(fù)責(zé)網(wǎng)絡(luò)爬蟲的調(diào)度及數(shù)據(jù)的獲取、清洗和融合。數(shù)據(jù)層分為七部分:調(diào)度器、調(diào)度器中間件、下載器、下載器中間件、解析器、解析器中間件和存儲管道。Scrapy引擎,用來處理整個系統(tǒng)的數(shù)據(jù)流處理,觸發(fā)事務(wù);解析器中間件,介于Scrapy引擎和解析器之間的鉤子框架,主要工作是處理Spider的響應(yīng)輸入和請求輸出,包括漏洞信息的清洗工作。數(shù)據(jù)層繼承Spider類,并重寫parse(response)方法,在各個子類中可以選擇抓取數(shù)據(jù)的模式和日期,抓取數(shù)據(jù)的模式分為循環(huán)抓取、定時抓取和范圍抓取。
調(diào)度器中間件,介于Scrapy引擎和調(diào)度器之間的中間件,從Scrapy引擎發(fā)送到調(diào)度的請求和響應(yīng);調(diào)度器,用來接受引擎發(fā)過來的請求,壓入隊列中,并在引擎再次請求的時候返回,本文通過使用Scrapy-Redis存儲調(diào)度redis的訪問請求,實(shí)現(xiàn)分布式任務(wù)調(diào)度和爬取功能,網(wǎng)頁調(diào)度功能由重寫Scrapy引擎的Spider類實(shí)現(xiàn),系統(tǒng)從調(diào)度器中取出一個鏈接(URL)用于接下來的抓取;調(diào)度器把URL封裝成一個請求(Request)傳給下載器;下載器把資源下載下來,并封裝成應(yīng)答包(Response);爬蟲解析Response;解析出實(shí)體(Item),則交給實(shí)體管道進(jìn)行進(jìn)一步的處理;解析出的是鏈接(URL),則把URL交給調(diào)度器等待抓取。下載器中間件,位于Scrapy引擎和下載器之間的鉤子框架,主要是處理Scrapy引擎與下載器之間的請求及響應(yīng),數(shù)據(jù)層繼承DownloaderMiddleware類,并重寫process_request(request,spider)方法,分別設(shè)計了RotateUserAgentMiddleware類(提供隨機(jī)的偽裝User-Agent頭)、CookiesMiddleware類(負(fù)責(zé)cookies追蹤和維護(hù))和HttpProxyMiddleware類(提供IP代理接口),其具體設(shè)計如圖1所示。
2.2? 業(yè)務(wù)層設(shè)計與實(shí)現(xiàn)
業(yè)務(wù)層是本系統(tǒng)的關(guān)鍵所在,本系統(tǒng)的所有業(yè)務(wù)邏輯功能和相關(guān)算法皆在本層實(shí)現(xiàn),具體設(shè)計如圖2所示。使用業(yè)務(wù)層的優(yōu)勢在于可以降低表示層和數(shù)據(jù)層的功能復(fù)雜度,使表示層專注于請求響應(yīng),使數(shù)據(jù)層專注于數(shù)據(jù)操作,這樣不僅使系統(tǒng)結(jié)構(gòu)清晰,而且可以最大程度上實(shí)現(xiàn)系統(tǒng)松耦合,便于業(yè)務(wù)功能的擴(kuò)展和屏蔽接口具體實(shí)現(xiàn)細(xì)節(jié),能夠增強(qiáng)系統(tǒng)的擴(kuò)展性和穩(wěn)定性。
2.3? 網(wǎng)頁判重模塊設(shè)計與實(shí)現(xiàn)
在網(wǎng)絡(luò)爬蟲運(yùn)行過程中,可能存在同一頁面被多次下載的情況,不僅會延長運(yùn)行時間,還會為增加系統(tǒng)負(fù)荷。本文通過控制URL下載隊列中的URL唯一性,解決爬取URL的重復(fù)性問題。首先在系統(tǒng)中建立一個全局變量,用于監(jiān)測是否某一URL曾被訪問過;然后在爬取過程中探測當(dāng)前待爬取URL是否在全局變量中,即可完成URL的判重工作。本文建立一個URL去重池,在下載過程中,在去重池里的URL有且僅有一次爬取動作。
本文采用基于Hash算法的MD5壓縮映射存儲,實(shí)現(xiàn)URL去重池的功能。爬取過程中,MD5算法能夠?qū)⑷我馕粩?shù)的字符串壓縮為128位整數(shù),并映射為物理地址,且MD5進(jìn)行Hash映射碰撞的概率非常小,幾乎可以忽略不計,可以實(shí)現(xiàn)URL去重池的唯一性。在爬蟲每一次爬取過程中,將在MD5存儲時發(fā)生碰撞的URL左移一位,對URL進(jìn)行重復(fù)MD5處理。網(wǎng)頁判重流程圖如圖3所示。
本系統(tǒng)使用Scrapy框架中的Spider類,網(wǎng)絡(luò)爬蟲模塊類繼承Spider類,并實(shí)現(xiàn)start_request()方法,dont_filter參數(shù)設(shè)為False。本模塊首先獲取Url地址,接著采用MD5[45]壓縮算法將Url地址壓縮成長度為128位整數(shù)并映射成物理地址;隨后判斷整數(shù)是否重復(fù):若不重復(fù),則將MD5串存入去重庫中并將Url地址加入請求隊列中;若重復(fù),則判斷是否發(fā)生碰撞(MD5串相同的情況下,Url地址不同,稱為發(fā)生碰撞。),若產(chǎn)生未產(chǎn)生碰撞,則丟棄Url地址;否則將Url地址左移一位重新進(jìn)行MD5壓縮并比較是否重復(fù),直至結(jié)束。
2.4? 網(wǎng)頁下載模塊設(shè)計與實(shí)現(xiàn)
網(wǎng)頁下載模塊在網(wǎng)頁判重模塊之后,本系統(tǒng)使用Scrapy框架中的下載器中間件(處理Scrapy引擎與下載器之間的請求及響應(yīng)),繼承DownloaderMiddleware類,并重寫process_request(request,spider)方法。本系統(tǒng)先從請求隊列RequestQueue中提取Url地址,然后交給下載器中間件下載網(wǎng)頁內(nèi)容;若下載過程中出錯,則調(diào)用RotateUserAgentMiddleware類(提供隨機(jī)的偽裝User-Agent頭)、CookiesMiddleware類(負(fù)責(zé)cookies追蹤和維護(hù))和HttpProxyMiddleware類(提供IP代理接口),重新下載網(wǎng)頁內(nèi)容,重復(fù)此過程3次;若最終仍下載失敗,則將Url地址和MD5字符串存入失敗隊列FailQueue中,等待存入數(shù)據(jù)庫中。網(wǎng)頁下載流程圖如圖4所示。
3? 實(shí)驗結(jié)果
3.1? 實(shí)驗數(shù)據(jù)
為驗證本文研究的基于Scrapy框架的分布式網(wǎng)絡(luò)爬蟲系統(tǒng)的高效率和穩(wěn)定性,以hao123為測試頁面,設(shè)置對照驗證試驗,其中本文研究的網(wǎng)絡(luò)爬蟲系統(tǒng)為實(shí)驗組,傳統(tǒng)單機(jī)網(wǎng)絡(luò)爬蟲系統(tǒng)為對照組。在實(shí)驗組中通過將url.py文件產(chǎn)生的url隊列存入至redis數(shù)據(jù)庫隊列內(nèi),再使用scrapy crawl命令執(zhí)行分布式爬取,最后將數(shù)據(jù)存入MongoDB中;而對照組采用傳統(tǒng)的Nutch網(wǎng)絡(luò)爬蟲進(jìn)行數(shù)據(jù)抓取,分別測試實(shí)驗組以及對照組在不同的網(wǎng)頁數(shù)抓取過程中成功下載保存的網(wǎng)頁數(shù)量,網(wǎng)頁抓取統(tǒng)計結(jié)果如表1所示。
3.2? 實(shí)驗結(jié)果
根據(jù)上表1所示,對照組在進(jìn)行網(wǎng)頁抓取時,網(wǎng)頁丟失數(shù)量較多、抓取時間較長,實(shí)驗組的網(wǎng)頁抓取成功率和運(yùn)行效率明顯提升,訪問時間明顯降低,證明本文研究的基于Scrapy框架的分布式網(wǎng)絡(luò)爬蟲系統(tǒng)具有優(yōu)越性,可被廣泛應(yīng)用推廣。
4? 結(jié)? 論
通過設(shè)計基于Scrapy框架的分布式網(wǎng)絡(luò)爬蟲系統(tǒng),改進(jìn)并優(yōu)化了傳統(tǒng)Scrapy框架,拓展了Scrapy框架的分布式能力,實(shí)現(xiàn)網(wǎng)絡(luò)爬蟲的分布式抓取和數(shù)據(jù)的非結(jié)構(gòu)化存儲,經(jīng)實(shí)驗結(jié)果發(fā)現(xiàn)基,基于Scrapy框架的分布式網(wǎng)絡(luò)爬蟲系統(tǒng)相較傳統(tǒng)單機(jī)網(wǎng)絡(luò)爬蟲系統(tǒng),提升了網(wǎng)絡(luò)爬蟲的抓取效率和運(yùn)行穩(wěn)定性。
參考文獻(xiàn):
[1] 米切爾.Python網(wǎng)絡(luò)數(shù)據(jù)采集 [M].南京:東南大學(xué)出版社,2018.
[2] YU J K,LI M R,ZHANG D Y. A Distributed Web Crawler Model based on Cloud Computing [C]//The 2nd Information Technology and Mechatronics Engineering Conference (ITOEC 2016).2016:276-279.
[3] 劉順程,岳思穎.大數(shù)據(jù)時代下基于Python的網(wǎng)絡(luò)信息爬取技術(shù) [J].電子技術(shù)與軟件工程,2017(21):160.
[4] 施威,夏斌.基于Scrapy的商品評價獲取系統(tǒng)設(shè)計 [J].微型機(jī)與應(yīng)用,2017,36(19):12-15.
[5] 劉碩.精通scrapy網(wǎng)絡(luò)爬蟲 [M].北京:清華大學(xué)出版社,2017.
[6] 徐海嘯,董颯,李翔,等.分布式網(wǎng)絡(luò)爬蟲框架Crawlzilla [J].電子技術(shù)與軟件工程,2017(18):25-26.
作者簡介:周毅(1992—),男,漢族,遼寧鞍山人,中級工程師,碩士研究生,研究方向:信息通信;李威(1980—),男,漢族,遼寧鞍山人,高級工程師,碩士研究生,研究方向:信息通信;何金(1983—),男,漢族,遼寧阜新人,高級工程師,本科,研究方向:信息通信;程蕾(1990—),女,漢族,遼寧凌源人,中級工程師,碩士研究生,研究方向:信息通信;柳璐(1992—),女,漢族,遼寧東港人,中級工程師,碩士研究生,研究方向:信息通信。