關(guān)鍵詞:Scrapy 框架;分布式;網(wǎng)絡(luò)爬蟲系統(tǒng)
中圖分類號(hào):TP393.09 文獻(xiàn)標(biāo)識(shí)碼:A
0 引言
在大數(shù)據(jù)時(shí)代背景下,各個(gè)行業(yè)產(chǎn)生了海量的數(shù)據(jù),為保證萬(wàn)維網(wǎng)數(shù)據(jù)搜索性能,市面上出現(xiàn)多種多樣的搜索引擎,搜索引擎在海量數(shù)據(jù)的快速搜集中發(fā)揮重要作用。同時(shí),隨著網(wǎng)絡(luò)信息數(shù)據(jù)規(guī)模的不斷增加和發(fā)展,用戶對(duì)信息搜索引擎提出了更高的要求[1]。網(wǎng)絡(luò)爬蟲技術(shù)應(yīng)運(yùn)而生,該技術(shù)可以自動(dòng)搜集和整理互聯(lián)網(wǎng)信息數(shù)據(jù),并向指定的數(shù)據(jù)庫(kù)傳輸和存儲(chǔ)相關(guān)信息[2]。但是傳統(tǒng)單機(jī)網(wǎng)絡(luò)爬蟲存在抓取效率低、穩(wěn)定性低、數(shù)據(jù)量不足等問題,無(wú)法滿足大數(shù)據(jù)時(shí)代對(duì)海量數(shù)據(jù)的搜索需求。為解決以上問題,本文應(yīng)用Scrapy 框架,對(duì)分布式網(wǎng)絡(luò)爬蟲系統(tǒng)進(jìn)行設(shè)計(jì)和應(yīng)用。
1 系統(tǒng)設(shè)計(jì)關(guān)鍵技術(shù)
1.1 網(wǎng)絡(luò)爬蟲工作原理
網(wǎng)絡(luò)爬蟲作為一種重要的計(jì)算機(jī)程序,可以嚴(yán)格按照相關(guān)規(guī)則從互聯(lián)網(wǎng)中抓取相關(guān)信息數(shù)據(jù)。網(wǎng)絡(luò)爬蟲工作原理如下:首先,借助有序的待爬行隊(duì)列,存儲(chǔ)各個(gè)統(tǒng)一資源定位符(uniform resourcelocation,URL)隊(duì)列。其次,嚴(yán)格按照相關(guān)隊(duì)列順序,從待爬行隊(duì)列中抓取URL,將網(wǎng)絡(luò)請(qǐng)求發(fā)送至URL 地址,從而獲得所需要的網(wǎng)頁(yè)內(nèi)容,對(duì)該網(wǎng)頁(yè)內(nèi)容進(jìn)行全面分析并提取新的URL。最后,按照一定的順序,將提取的URL 存儲(chǔ)至待爬行隊(duì)列中,不斷重復(fù)以上操作,當(dāng)待爬行隊(duì)列滿足所設(shè)置好的爬行終止條件時(shí),即可結(jié)束[3]。
1.2 Scrapy 框架
Scrapy 框架作為一種重要的應(yīng)用框架,主要應(yīng)用于結(jié)構(gòu)化網(wǎng)絡(luò)資源的提取和通用網(wǎng)絡(luò)爬蟲系統(tǒng)的構(gòu)建。Scrapy 框架包含引擎、蜘蛛中間件、調(diào)度中間件、調(diào)度器、下載器中間件、下載器、項(xiàng)目管道等組成部分,通過(guò)應(yīng)用異步網(wǎng)絡(luò)庫(kù),可以保證網(wǎng)絡(luò)通信處理質(zhì)量和效率。目前,Scrapy 框架被廣泛應(yīng)用于數(shù)據(jù)挖掘、數(shù)據(jù)監(jiān)測(cè)、系統(tǒng)測(cè)試等領(lǐng)域中,并取得了良好的應(yīng)用效果[4]。
2 系統(tǒng)總體設(shè)計(jì)
2.1 系統(tǒng)架構(gòu)設(shè)計(jì)
如圖1 所示,系統(tǒng)架構(gòu)被劃分為以下3 個(gè)部分。
(1)調(diào)度層。調(diào)度層可實(shí)時(shí)接收從Scrapy 引擎中發(fā)送的請(qǐng)求,并將該請(qǐng)求直接存儲(chǔ)至指定隊(duì)列中,便于后期Scrapy 引擎再次請(qǐng)求時(shí)可快速返回和獲取。本文運(yùn)用存儲(chǔ)調(diào)度的方式,對(duì)遠(yuǎn)程字典服務(wù)(remote dictionary server,Redis)訪問請(qǐng)求進(jìn)行調(diào)度,從而達(dá)到智能化調(diào)度和爬取分布式任務(wù)的目的。本文系統(tǒng)借助調(diào)度層,可以實(shí)現(xiàn)對(duì)單個(gè)URL鏈接的提取和封裝,當(dāng)URL 封裝成指定的請(qǐng)求時(shí),需將該請(qǐng)求直接發(fā)送至下載器,由下載器搜索和下載所需要的資源。在進(jìn)行爬蟲解析請(qǐng)求時(shí),可解析出相應(yīng)的實(shí)體,并將該實(shí)體發(fā)送至實(shí)體管道,由實(shí)體管道對(duì)該實(shí)體采取進(jìn)一步處理[5]。當(dāng)URL 鏈接成功解析后,可向調(diào)度層發(fā)送解析后的URL 地址,由調(diào)度層等待抓取。
(2)中間件層。中間件層主要包含Cookies 中間件、Proxy 中間件、UA 中間件、Retry 中間件等組成部分。其中,Cookies 中間件主要用于對(duì)用戶本地終端數(shù)據(jù)的安全化存儲(chǔ),方便后期系統(tǒng)快速辨別不同用戶的身份信息,保證會(huì)話跟蹤實(shí)現(xiàn)效果;Proxy 中間件主要用于對(duì)代理池進(jìn)行對(duì)接處理,方便系統(tǒng)快速識(shí)別不同目標(biāo)網(wǎng)站服務(wù)器的IP 地址;用戶代理(user agent,UA)中間件主要用于對(duì)添加錯(cuò)誤UA 信息的實(shí)時(shí)修改和更新;Retry 中間件主要用于對(duì)運(yùn)行異常代理的重寫和改進(jìn)。
(3)數(shù)據(jù)層。數(shù)據(jù)層主要利用MongoDB 數(shù)據(jù)庫(kù),獲取、清洗和融合處理數(shù)據(jù)。整個(gè)數(shù)據(jù)層在具體設(shè)計(jì)時(shí),主要繼承Spider 類,該 Spider 類定義了如何爬取某個(gè)網(wǎng)站,應(yīng)用該子類可以對(duì)請(qǐng)求方法進(jìn)行重寫,并實(shí)時(shí)選擇和抓取數(shù)據(jù)模式和日期。
2.2 系統(tǒng)數(shù)據(jù)庫(kù)設(shè)計(jì)
在本文系統(tǒng)中,主要運(yùn)用MongoDB 數(shù)據(jù)庫(kù),從而實(shí)現(xiàn)長(zhǎng)時(shí)間存儲(chǔ)數(shù)據(jù)。在設(shè)計(jì)MongoDB 數(shù)據(jù)庫(kù)時(shí),需設(shè)計(jì)合理的數(shù)據(jù)表結(jié)構(gòu),保證系統(tǒng)數(shù)據(jù)庫(kù)的穩(wěn)定性和可靠性。在網(wǎng)絡(luò)爬蟲期間,主要目標(biāo)網(wǎng)站為微博和脈脈。對(duì)于微博目標(biāo)網(wǎng)站,重點(diǎn)關(guān)注微博條目詳細(xì)信息、用戶詳細(xì)信息等數(shù)據(jù);對(duì)于脈脈目標(biāo)網(wǎng)站,重點(diǎn)關(guān)注匿名消息條目詳情、反饋消息等數(shù)據(jù)。因此,本文系統(tǒng)設(shè)計(jì)了微博條目表、微博用戶表、脈脈詳細(xì)表。其中,微博條目表主要包含微博編號(hào)、點(diǎn)贊量、轉(zhuǎn)發(fā)量、文本、原始文本、創(chuàng)建實(shí)際等屬性;微博用戶表主要包含微博編號(hào)、用戶名、頭像路徑、用戶描述、粉絲數(shù)量等屬性;脈脈詳細(xì)表主要包含數(shù)據(jù)源、評(píng)論量、插入時(shí)間、消息類型、發(fā)布時(shí)間、站點(diǎn)名等屬性。
3 系統(tǒng)功能模塊設(shè)計(jì)
本文系統(tǒng)主要用于對(duì)微博、脈脈目標(biāo)網(wǎng)站相關(guān)數(shù)據(jù)進(jìn)行實(shí)時(shí)爬取。整個(gè)系統(tǒng)功能模塊經(jīng)過(guò)細(xì)化后,得到代理池服務(wù)、實(shí)體管道、網(wǎng)頁(yè)判重、網(wǎng)頁(yè)下載等模塊,各個(gè)模塊設(shè)計(jì)流程如下。
3.1 代理池服務(wù)模塊設(shè)計(jì)
代理池服務(wù)模塊主要包含以下4 個(gè)子模塊:①獲取模塊。在獲取模塊中,用戶可以借助本文系統(tǒng)提供的代理網(wǎng)站,抓取需要的代理信息。代理既可以免費(fèi)使用,也可以付費(fèi)使用。整個(gè)獲取模塊中,可以從多個(gè)數(shù)據(jù)來(lái)源中獲取所需要的數(shù)據(jù),當(dāng)數(shù)據(jù)被成功抓取后,可以將其直接傳輸和存儲(chǔ)至數(shù)據(jù)庫(kù)。②存儲(chǔ)模塊。存儲(chǔ)模塊主要用于代理信息的統(tǒng)一存儲(chǔ)和抓取,為保證代理的唯一性,需標(biāo)識(shí)不同代理的處理狀態(tài)。③檢測(cè)模塊。在檢測(cè)模塊中,用戶可以借助存儲(chǔ)模塊,對(duì)系統(tǒng)數(shù)據(jù)庫(kù)中的代理信息進(jìn)行統(tǒng)一檢測(cè),結(jié)合最終檢測(cè)結(jié)果,標(biāo)識(shí)和設(shè)置不同代理相應(yīng)的分?jǐn)?shù)狀態(tài)。④接口模塊。接口模塊可以直接訪問系統(tǒng)數(shù)據(jù)庫(kù),快速獲取需要的數(shù)據(jù),但是這種操作缺乏安全性,容易導(dǎo)致數(shù)據(jù)庫(kù)內(nèi)配置信息丟失、泄露等。為解決以上問題,本文重點(diǎn)設(shè)計(jì)接口模塊,用戶借助接口模塊,可以安全、快速地獲取需要的代理信息,保證代理信息獲取機(jī)會(huì)的均等性,提高本文系統(tǒng)整體負(fù)載均衡能力。
3.2 實(shí)體管道模塊
實(shí)體管道模塊主要用于對(duì)爬取數(shù)據(jù)的清洗、驗(yàn)證和存儲(chǔ)等相關(guān)處理。該模塊主要包含微博實(shí)體管道、脈脈實(shí)體管道等多個(gè)子模塊,各個(gè)子模塊之間既相互獨(dú)立,又相互依賴,按照流水線方式進(jìn)行有序運(yùn)行。其中,微博實(shí)體管道模塊主要用于實(shí)時(shí)添加爬取時(shí)間字段,當(dāng)該時(shí)間字段信息添加完成后,本文系統(tǒng)可以自動(dòng)將添加好的時(shí)間字段信息存儲(chǔ)至MongoDB數(shù)據(jù)庫(kù);脈脈實(shí)體管道模塊設(shè)計(jì)目的是保證脈脈數(shù)據(jù)的獨(dú)特性和唯一性,避免脈脈數(shù)據(jù)重復(fù),當(dāng)脈脈數(shù)據(jù)經(jīng)過(guò)去重、清洗處理后,可以將該數(shù)據(jù)直接存儲(chǔ)至MongoDB 數(shù)據(jù)庫(kù),便于其他人員查看和調(diào)用。
3.3 網(wǎng)頁(yè)判重模塊
在網(wǎng)絡(luò)爬蟲運(yùn)行期間,為避免因同一頁(yè)面被多次下載而增加系統(tǒng)運(yùn)行時(shí)間和運(yùn)行負(fù)荷的情況,本文重點(diǎn)設(shè)計(jì)和實(shí)現(xiàn)網(wǎng)頁(yè)判重模塊,確保URL 下載隊(duì)列含有唯一的URL 和爬取URL 的唯一性。URL網(wǎng)頁(yè)判重工作具體流程為:首先,利用本文系統(tǒng)完成對(duì)單個(gè)全局變量的構(gòu)建,檢測(cè)和判斷某一URL是否被瀏覽和訪問過(guò);其次,還要對(duì)當(dāng)前待爬取URL 進(jìn)行探測(cè),探測(cè)其是否處于全局變量中。從圖2 可以看出, 運(yùn)用哈希算法, 獲取所需要的URL 地址,并且對(duì)信息摘要算法(message-digestalgorithm)MD5 進(jìn)行壓縮映射處理,保證URL 去重池功能的實(shí)現(xiàn)效果。在具體網(wǎng)絡(luò)爬蟲期間,運(yùn)用MD5 算法,可以對(duì)任意位數(shù)的字符串進(jìn)行壓縮,使其成為128 位整數(shù),并將該整數(shù)統(tǒng)一映射為指定的物理地址,確保URL 去重池具有一定的獨(dú)特性和唯一性。在單次爬取期間,如果映射物理地址出現(xiàn)重復(fù),需要檢驗(yàn)MD5 在存儲(chǔ)期間是否出現(xiàn)碰撞,如果出現(xiàn)碰撞,需對(duì)URL 中的二進(jìn)制數(shù)(10000)進(jìn)行左移一位,得到100000;如果未出現(xiàn)碰撞,需丟棄URL 地址。
3.4 網(wǎng)頁(yè)下載模塊
在具體設(shè)計(jì)網(wǎng)頁(yè)下載模塊時(shí),技術(shù)人員需要應(yīng)用Scrapy 框架內(nèi)部的Downloader Middleware 類,該類定義了一個(gè)或多個(gè)方法的類,運(yùn)用該類可以對(duì)process_request 方法進(jìn)行重寫。本文系統(tǒng)從指定的請(qǐng)求隊(duì)列中,完成對(duì)特定URL 地址的提取,并將其發(fā)送至下載器中間件,由下載器中間件對(duì)所需要的網(wǎng)頁(yè)內(nèi)容進(jìn)行下載,如果網(wǎng)頁(yè)內(nèi)容下載期間出現(xiàn)錯(cuò)誤問題,需調(diào)用Rotate User Agent Middleware 類,對(duì)網(wǎng)頁(yè)內(nèi)容進(jìn)行重新下載,整個(gè)下載過(guò)程重復(fù)3 次,當(dāng)重復(fù)下載3 次結(jié)束后,仍然下載失敗,則需借助失敗隊(duì)列存儲(chǔ)URL 地址和相關(guān)字符。網(wǎng)頁(yè)下載流程如圖3 所示。
4 系統(tǒng)測(cè)試
為驗(yàn)證本文系統(tǒng)的高效性和穩(wěn)定性,本文以“hao123”為測(cè)試頁(yè)面,并將本文系統(tǒng)和傳統(tǒng)單機(jī)網(wǎng)絡(luò)爬蟲系統(tǒng)分別設(shè)置為實(shí)驗(yàn)組和對(duì)照組。在實(shí)驗(yàn)組中,主要用到url.py 文件,該文件在具體使用中,通常產(chǎn)生大量的URL 隊(duì)列,此時(shí),需利用Redis數(shù)據(jù)庫(kù)完成對(duì)以上URL 隊(duì)列的存儲(chǔ);同時(shí),應(yīng)用Scrapy crawl 命令,保證分布式抓取執(zhí)行效率和效果;最后應(yīng)用MongoDB 數(shù)據(jù)庫(kù),存儲(chǔ)相關(guān)數(shù)據(jù)。在對(duì)照組中,主要運(yùn)用傳統(tǒng)Nutch 網(wǎng)絡(luò)爬蟲,抓取和存儲(chǔ)相關(guān)數(shù)據(jù)。在進(jìn)行網(wǎng)頁(yè)數(shù)據(jù)抓取期間,本文分別測(cè)試實(shí)驗(yàn)組、對(duì)照組成功下載保存網(wǎng)頁(yè)數(shù)量,網(wǎng)頁(yè)抓取統(tǒng)計(jì)結(jié)果如表1 所示。從表1 中的數(shù)據(jù)可以看出,與對(duì)照組相比,實(shí)驗(yàn)組在進(jìn)行網(wǎng)頁(yè)抓取時(shí),網(wǎng)頁(yè)抓取成功率和運(yùn)行效率明顯得到提升,訪問時(shí)間有效縮短,這說(shuō)明本文系統(tǒng)在網(wǎng)頁(yè)抓取和運(yùn)行方面具有顯著優(yōu)勢(shì)。
5 結(jié)語(yǔ)
綜上,本文應(yīng)用Scrapy 框架所設(shè)計(jì)的分布式網(wǎng)絡(luò)爬蟲系統(tǒng)在改進(jìn)和優(yōu)化傳統(tǒng)Scrapy 框架的基礎(chǔ)上,對(duì)Scrapy 框架分布式能力進(jìn)行不斷拓展和提升,不僅保證網(wǎng)絡(luò)爬蟲分布式抓取效果,還能實(shí)現(xiàn)對(duì)相關(guān)數(shù)據(jù)的非結(jié)構(gòu)化存儲(chǔ)。本文系統(tǒng)具有網(wǎng)頁(yè)抓取成功率高、運(yùn)行效率高等特點(diǎn),表現(xiàn)出一定的應(yīng)用價(jià)值和應(yīng)用前景,值得被進(jìn)一步推廣和應(yīng)用。