馬 蕾,馮錫煒,竇予梓,高天鑄,朱 睿,吳衍兵
(遼寧石油化工大學(xué) 計(jì)算機(jī)與通信工程學(xué)院,遼寧 撫順 113001)
網(wǎng)絡(luò)爬蟲(chóng),是能夠按照程序設(shè)計(jì)者所指定的要求,有序、自動(dòng)地獲取指定網(wǎng)站中有用信息的程序。根據(jù)性能和所用技術(shù)的不同,爬蟲(chóng)的種類(lèi)可以分為很多種[1]。
傳統(tǒng)的單機(jī)爬蟲(chóng),只有一個(gè)單一的本地爬取隊(duì)列,內(nèi)存空間小,計(jì)算空間小,在需要爬取海量數(shù)據(jù)的情況下,已經(jīng)不能滿足實(shí)際需求。因此需要找出方法,解決這些問(wèn)題,優(yōu)化爬取方式,改進(jìn)解析規(guī)則,使爬取出的數(shù)據(jù)更精準(zhǔn)、爬取過(guò)程更快速[2]。
將分布式的思想引用到網(wǎng)絡(luò)爬蟲(chóng)中,分布式文件系統(tǒng)和大型分布式并行計(jì)算框架的使用,提高了爬蟲(chóng)在速度和準(zhǔn)確度上的性能。通過(guò)搭建分布式集群,擴(kuò)充了工作資源。通過(guò)設(shè)計(jì)爬取流程合理分配空間、對(duì)抓取隊(duì)列進(jìn)行管理、優(yōu)化爬取規(guī)則、擴(kuò)充算法,使分布式爬蟲(chóng)的抓取過(guò)程更流暢合理[3]。
文中所研究的基于Nutch的分布式爬蟲(chóng)就適用于針對(duì)大批量數(shù)據(jù)的操作,其可編寫(xiě)插件的機(jī)制利于爬蟲(chóng)的模塊化和可擴(kuò)展化。Nutch提供了可擴(kuò)展接口,用于擴(kuò)展爬蟲(chóng)功能,編寫(xiě)不同的插件可實(shí)現(xiàn)不同的操作,根據(jù)不同的需求可實(shí)現(xiàn)自定義功能。開(kāi)源的全文搜索框架Solr直接搜索Nutch獲取的頁(yè)面信息,為爬取下來(lái)的頁(yè)面維護(hù)一個(gè)索引,也可對(duì)抓取結(jié)果進(jìn)行復(fù)雜條件查詢(xún)、模糊查詢(xún)。在爬取時(shí),可以指定數(shù)據(jù)源獲取信息,使抓取更有針對(duì)性和目的性[4-7]。
Nutch依賴(lài)于Hadoop,在Hadoop集群中運(yùn)行可以用于對(duì)爬取任務(wù)的批處理。利用HDFS分布式文件系統(tǒng)對(duì)所有的數(shù)據(jù)進(jìn)行訪問(wèn)與管理,并將MapReduce大型分布式并行計(jì)算架構(gòu)與HDFS無(wú)縫結(jié)合。在分布式集群中,利用Zookeeper分布式協(xié)調(diào)服務(wù),對(duì)分布式各個(gè)服務(wù)提供輔助功能,保證集群高效可用[8-9]。
在實(shí)際項(xiàng)目中采用Redis這種高性能的Key-Value數(shù)據(jù)庫(kù)對(duì)數(shù)進(jìn)行存儲(chǔ),運(yùn)用Solr分布式高性能全文搜索引擎,支持對(duì)文件、文本等數(shù)據(jù)源建立索引,提供毫秒級(jí)查詢(xún)。選擇用Squid高性能代理緩存服務(wù)器,它支持FTP、gopher、HTTPS和HTTP協(xié)議,這樣能更好地接受來(lái)自需要下載的目標(biāo)的請(qǐng)求,并且處理這些請(qǐng)求,獲取到信息后,Squid會(huì)復(fù)制一份,以便下次使用[10]。
Nutch作為一種透明,開(kāi)源,基于Java語(yǔ)言的搜索引擎框架,提供了非常全面的工具,全文搜索和Web爬蟲(chóng)[11]。
設(shè)計(jì)的爬蟲(chóng)工作流程如圖1所示,總體分為以下幾個(gè)步驟:
圖1 爬蟲(chóng)工作流程
(1)獲取到網(wǎng)頁(yè)的內(nèi)容,即下載網(wǎng)頁(yè)。需要通過(guò)向目標(biāo)服務(wù)器發(fā)送請(qǐng)求并等待響應(yīng),服務(wù)器響應(yīng)后就能得到想要獲取的內(nèi)容信息;
(2)解析所得到的信息內(nèi)容,獲取到有用的信息。并通過(guò)解析到的信息,同時(shí)找到其中新的URL加入爬取隊(duì)列,獲取新的頁(yè)面;
(3)涉及到對(duì)爬取出的數(shù)據(jù)保存的問(wèn)題,分布式爬蟲(chóng)需要保存的數(shù)據(jù)多樣化,而且數(shù)據(jù)量大,通過(guò)Redis這種Key-Value數(shù)據(jù)庫(kù)對(duì)數(shù)進(jìn)行存儲(chǔ)。
Nutch具有強(qiáng)大的可擴(kuò)展性,有四個(gè)可擴(kuò)展點(diǎn),可通過(guò)編寫(xiě)其插件實(shí)現(xiàn)自定義功能,項(xiàng)目的抓取流程定義如下:
(1)程序會(huì)創(chuàng)建一個(gè)WebDb文件夾,這個(gè)WebDb文件夾用來(lái)存放將要抓取的URL。
(2)根據(jù)WebDb中內(nèi)容生成fetchlist,并將fetchlist寫(xiě)入到相應(yīng)的segment,每個(gè)segment內(nèi)最終存儲(chǔ)的是一次抓取循環(huán)中抓到的網(wǎng)頁(yè)和網(wǎng)頁(yè)的索引。
(3)可以根據(jù)這些fetchlist中的URL抓取所要的網(wǎng)頁(yè)。
(4)從網(wǎng)頁(yè)中獲取到新的URL,將這些新得到的URL加入到WebDb中,更新WebDb。
循環(huán)進(jìn)行前面的步驟,直至達(dá)到之前預(yù)先設(shè)定的抓取深度。
(5)可以根據(jù)WebDb得到的網(wǎng)頁(yè)評(píng)分和links更新segments;
(6)對(duì)所抓取的網(wǎng)頁(yè)進(jìn)行索引,在索引中,要丟棄掉擁有重復(fù)內(nèi)容的網(wǎng)頁(yè)和重復(fù)的URL。
(7)將segments中的索引進(jìn)行合并生成用于檢索的最終index索引。
上面是定義的基本抓取流程,在實(shí)際的抓取過(guò)程當(dāng)中,采用的是廣度優(yōu)先抓取的方法,它貼近所爬取的大部分網(wǎng)站的層次和結(jié)構(gòu),網(wǎng)站相鄰模塊間的內(nèi)容更具有關(guān)聯(lián)性。在爬取時(shí),廣度優(yōu)先策略可以避免對(duì)一個(gè)網(wǎng)站服務(wù)器在一段時(shí)間內(nèi)的反復(fù)訪問(wèn),可以減少對(duì)所爬取網(wǎng)站造成的影響[12]。
通過(guò)下載步驟之后獲取到的網(wǎng)頁(yè),要對(duì)其進(jìn)行解析處理,才能從中獲取到所需要的價(jià)值信息。傳統(tǒng)的獲取頁(yè)面內(nèi)容的方法為使用XPath語(yǔ)句,正則表達(dá)式,或者css選擇器。運(yùn)用這些方式,首先要找到網(wǎng)頁(yè)中的節(jié)點(diǎn),即元素、屬性、文本、命名空間等。例如,XPath使用路徑表達(dá)式來(lái)選取XML文檔中的節(jié)點(diǎn)或者節(jié)點(diǎn)集。
通過(guò)上述方法來(lái)獲取結(jié)果,不僅需要提前知道網(wǎng)頁(yè)的結(jié)構(gòu)邏輯,且對(duì)于所要獲取信息,不同的網(wǎng)站信息所處的位置不同,標(biāo)簽不同,網(wǎng)頁(yè)結(jié)構(gòu)不同,這樣不可能對(duì)所有頁(yè)面做出統(tǒng)一規(guī)則。在爬取大量網(wǎng)頁(yè)時(shí),消耗的人力和時(shí)間較多。因?yàn)镹utch可以嵌入算法,在總結(jié)大量網(wǎng)頁(yè)的情況并且對(duì)現(xiàn)有的解析算法進(jìn)行優(yōu)化后,設(shè)計(jì)了一種通用的算法將正文提取出來(lái),也使其能更好地與爬蟲(chóng)框架貼合[12-15]。
通過(guò)對(duì)項(xiàng)目的實(shí)現(xiàn),對(duì)大量數(shù)據(jù)的爬取實(shí)驗(yàn),對(duì)數(shù)據(jù)進(jìn)行驗(yàn)證和分析,得出以下實(shí)驗(yàn)結(jié)果。
Nutch是基于Linux系統(tǒng)內(nèi)核的框架,所以項(xiàng)目框架要發(fā)布運(yùn)行在Linux系統(tǒng)的服務(wù)器上。項(xiàng)目采用三臺(tái)CentOS 7服務(wù)器來(lái)搭建分布式集群,CentOS是Linux系統(tǒng),具有高度穩(wěn)定性。集群組件以Yarn、HDFS、Zookeeper、Solr為主,并且支持橫向擴(kuò)展。集群中NodeManager內(nèi)存12 G,內(nèi)核六顆,Container 1 G內(nèi)存。爬蟲(chóng)集群角色如圖2所示。
圖2 爬蟲(chóng)集群角色
在爬蟲(chóng)的獲取頁(yè)面信息的模塊中,設(shè)計(jì)了按照文本密集程度來(lái)找到正文的算法。以一篇文章為例,正文的部分主要集中在一定范圍內(nèi),且密集度高,其他部分相對(duì)松散不密集,不是要提取的正文部分,按照此特征,可以將算法實(shí)現(xiàn)[16-18]。
首先要對(duì)頁(yè)面進(jìn)行去除標(biāo)簽的處理,例如“
…”等,去除標(biāo)簽后再得到的文本信息,可以降低標(biāo)簽對(duì)所要提取內(nèi)容的干擾。去除標(biāo)簽后,取文本的行號(hào),對(duì)文本進(jìn)行計(jì)算,設(shè)定以每五行文本為一組,將五行中所有的字符數(shù)加起來(lái)取到和,用第一行的字符數(shù)除以五行累加的字符數(shù)和,得到一個(gè)比值d。其中,M的值為每一行的字符數(shù)目和。
然后,從第二行開(kāi)始,計(jì)算五行所有的字符數(shù)和,用第二行的字符數(shù)除以五行累加的字符數(shù)和,得到一個(gè)比值d,再按照第三行計(jì)算,以此類(lèi)推重復(fù)計(jì)算直到最后。在后面行數(shù)不足五行時(shí)總數(shù)按照后五行總數(shù)計(jì)算。如果在計(jì)算中,連續(xù)幾個(gè)得到的數(shù)值大于確定的閾值時(shí),可以判斷從第一個(gè)大的數(shù)值所在行開(kāi)始,進(jìn)入正文部分。
關(guān)于d的閾值,經(jīng)過(guò)大量實(shí)際處理調(diào)整,實(shí)驗(yàn)統(tǒng)計(jì),計(jì)算得出一個(gè)合適的數(shù)值,經(jīng)過(guò)專(zhuān)家建議將閾值設(shè)置為0.2。所以d的值數(shù)一般在0.2左右,可以判定為進(jìn)入正文部分了。
在抽取頁(yè)面信息的過(guò)程中,對(duì)于新發(fā)現(xiàn)的URL是否加入爬取隊(duì)列,會(huì)有去重機(jī)制。對(duì)爬取過(guò)的網(wǎng)頁(yè)信息,會(huì)建立一個(gè)索引,一起存在WebDb中,新發(fā)現(xiàn)的URL會(huì)與爬取過(guò)的URL進(jìn)行對(duì)比,如果爬取過(guò)直接丟棄不再重復(fù)爬取,沒(méi)有爬取過(guò)則增加索引加入到爬取隊(duì)列中并且更新WebDb??梢杂行Ч?jié)省爬取時(shí)間,節(jié)省資源,避免不必要的重復(fù)數(shù)據(jù)的加入,優(yōu)化爬取流程[19]。
通過(guò)搭建分布式集群,對(duì)上述抓取流程和解析過(guò)程的實(shí)現(xiàn),爬取了大量公司的官網(wǎng)網(wǎng)頁(yè)中所展示的內(nèi)容,規(guī)定爬取網(wǎng)站上盡可能全面的信息。爬取的網(wǎng)站數(shù)目多,每一家公司網(wǎng)站不相同,深度,樣式不統(tǒng)一,數(shù)據(jù)量就不能確定,因此不對(duì)爬取深度做要求。把爬取后的數(shù)據(jù)放入到Solr引擎中,Solr會(huì)對(duì)數(shù)據(jù)進(jìn)行管理,方便搜索。
通過(guò)測(cè)試發(fā)現(xiàn),分布式爬蟲(chóng)有很好的爬取性能。在Solr引擎中展示的所爬取的信息,其中有URL地址和所爬取的具體正文內(nèi)容。
運(yùn)用爬蟲(chóng)技術(shù)從網(wǎng)頁(yè)中爬取的信息數(shù)量龐大且有冗余,同時(shí)摻雜有用的數(shù)據(jù)和無(wú)用的數(shù)據(jù),因此,從大量所得的數(shù)據(jù)中提取出真正所需要的信息十分必要。普通的爬蟲(chóng)不能區(qū)分什么是有用的數(shù)據(jù),什么是無(wú)用的數(shù)據(jù)。以“市場(chǎng)占有率”的相關(guān)信息為例,從網(wǎng)絡(luò)中爬取并且存儲(chǔ)下來(lái)[20-22]。根據(jù)相應(yīng)指標(biāo)關(guān)鍵字,從數(shù)據(jù)中抽取有用信息的方法如下:
以獲取到的頁(yè)面信息為對(duì)象,首先要對(duì)文本進(jìn)行過(guò)濾處理,過(guò)濾掉文本中夾雜的“ ”換行符、空格等內(nèi)容,這些符號(hào)不必要且干擾后續(xù)分析。以句號(hào)“?!睘椴鸱址瑢?duì)文本進(jìn)行初步拆分。然后將拆分后的每一句話再進(jìn)行拆分,拆分成詞組的形式。根據(jù)指標(biāo)對(duì)應(yīng)的關(guān)鍵詞,對(duì)拆分好的詞組進(jìn)行權(quán)重計(jì)算,提取出權(quán)重大于0的句子,并且對(duì)其排序,根據(jù)權(quán)重排序,只取權(quán)重高的前三句話。其中權(quán)重的計(jì)算方法如下:
基于句子間的內(nèi)容覆蓋率,給定兩個(gè)句子Si和Sj,采用如下公式進(jìn)行計(jì)算:
其中,分子tk是在兩個(gè)句子中都出現(xiàn)的詞組的數(shù)量,|Si|是句子i的詞組數(shù),|Sj|是句子j的詞組數(shù)。
這兩個(gè)句子語(yǔ)義相關(guān),并將它們連接起來(lái),即權(quán)重:
Wij=Similarity(Si,Sj)
表1為對(duì)按照“市場(chǎng)占有率”此項(xiàng)指標(biāo)進(jìn)行匹配算法分析后的結(jié)果。
表1 算法解析后的結(jié)果
通過(guò)表1可以看出,通過(guò)對(duì)一些指標(biāo)的解析和匹配查找,分析出了所爬取網(wǎng)頁(yè)中和此項(xiàng)指標(biāo)相關(guān)聯(lián)的信息。例如,“市場(chǎng)占有率”此項(xiàng)指標(biāo),從采集到的數(shù)據(jù)中解析出所需信息,印證了在數(shù)據(jù)爬取階段,分布式爬蟲(chóng)可以自動(dòng)完成數(shù)據(jù)的收集、解析、格式化存儲(chǔ),所采集的數(shù)據(jù)全面、高效。
Nutch底層基于MapReduce,直接受益于分布式的所有優(yōu)點(diǎn),可以在集群中對(duì)資源進(jìn)行調(diào)配和監(jiān)控,可以很好地管理爬蟲(chóng)。
4.5.1 爬蟲(chóng)速度分析
在實(shí)驗(yàn)中,使用分布式爬蟲(chóng)和單機(jī)爬蟲(chóng)分別對(duì)相同的300家公司進(jìn)行抓取,要求按照域名,爬取每家公司官網(wǎng)中所有展示的允許爬取的信息,觀察爬蟲(chóng)速度上的性能。在爬取時(shí),分布式爬蟲(chóng)每次所抓取的公司數(shù)量大致成整數(shù)倍增加,以此來(lái)測(cè)定爬蟲(chóng)爬取數(shù)量對(duì)爬取速度的影響。單機(jī)爬蟲(chóng)因?yàn)槠渥陨硇阅芟拗?,在爬取過(guò)程中只能對(duì)每個(gè)公司分別爬取,在實(shí)驗(yàn)過(guò)程中單機(jī)爬蟲(chóng)爬取前相同50家公司時(shí),用了17個(gè)小時(shí)。為了對(duì)數(shù)據(jù)做比較分析,將分布式爬蟲(chóng)和單機(jī)爬蟲(chóng)爬取時(shí)間統(tǒng)一用分鐘做單位。單機(jī)爬蟲(chóng)和分布式爬蟲(chóng)抓取公司的數(shù)量,抓取此數(shù)目公司所花費(fèi)的時(shí)間和速度,對(duì)照如表2所示。
表2 爬蟲(chóng)所爬取的公司數(shù)量和抓取
圖3為單機(jī)爬蟲(chóng)和分布式爬蟲(chóng)爬取數(shù)量和平均抓取速度折線對(duì)比圖。可以看出,分布式爬蟲(chóng)在抓取大量信息上具有很強(qiáng)的優(yōu)勢(shì)。在一定范圍內(nèi),爬取的數(shù)據(jù)量越大,分布式爬蟲(chóng)速度越快,越能現(xiàn)實(shí)其分布式的優(yōu)點(diǎn)。而單機(jī)爬蟲(chóng)不僅操作繁瑣,在性能上也不及分布式爬蟲(chóng)。分布式爬蟲(chóng)在大量數(shù)據(jù)采集中優(yōu)勢(shì)明顯。
圖3 爬蟲(chóng)爬取數(shù)量和速度
4.5.2 爬蟲(chóng)數(shù)據(jù)量分析
對(duì)于爬蟲(chóng)所爬取的數(shù)據(jù)量的分析,要在一段規(guī)定的時(shí)間內(nèi),查看爬蟲(chóng)爬取的數(shù)據(jù)量,性能高的爬蟲(chóng)在實(shí)際的爬取作業(yè)中占有優(yōu)勢(shì)。一些所爬取的網(wǎng)站可能會(huì)有爬取時(shí)間的限制,在相同的較短的時(shí)間內(nèi),爬取的數(shù)據(jù)量越大,所收集的信息相對(duì)就越全面。實(shí)驗(yàn)過(guò)程中,分別用分布式爬蟲(chóng)和單機(jī)爬蟲(chóng)來(lái)爬取相同的公司,查看在相同的固定時(shí)間內(nèi)分別爬取的數(shù)據(jù)量。爬取的時(shí)間成遞增趨勢(shì),爬取的時(shí)間和對(duì)應(yīng)的所爬取的數(shù)據(jù)量如表3所示。
表3 爬蟲(chóng)爬取時(shí)間和對(duì)應(yīng)爬取數(shù)據(jù)量對(duì)照
圖4 基于Nutch的分布式爬蟲(chóng)和其它
表3為單機(jī)爬蟲(chóng)和分布式爬蟲(chóng)在統(tǒng)一規(guī)定時(shí)間內(nèi)爬取時(shí)間和對(duì)應(yīng)爬取數(shù)量的對(duì)照,體現(xiàn)了基于Nutch分布式爬蟲(chóng)在抓取大量信息上所具有的優(yōu)勢(shì)。在相同的時(shí)間內(nèi),分布式爬蟲(chóng)所抓取的數(shù)據(jù)量明顯多于普通單機(jī)爬蟲(chóng),相對(duì)而言,爬取信息自然也更全面。
圖4為基于Nutch的分布式爬蟲(chóng)和其它分布式爬蟲(chóng)爬取數(shù)據(jù)量對(duì)比柱狀圖,從數(shù)據(jù)中可以看出,在相同時(shí)間內(nèi),基于Nutch的分布式爬蟲(chóng)所抓取數(shù)據(jù)量在一定程度上明顯多于其它分布式爬蟲(chóng)所抓取的數(shù)據(jù)量,基于Nutch的分布式爬蟲(chóng)在性能上更優(yōu)。
通過(guò)調(diào)研和總結(jié),了解了目前網(wǎng)絡(luò)爬蟲(chóng)的存在價(jià)值和意義,分布式爬蟲(chóng)的優(yōu)勢(shì),以及實(shí)現(xiàn)方法等。通過(guò)對(duì)分布式集群環(huán)境的搭建,運(yùn)用Nutch對(duì)大量網(wǎng)站的爬取、解析,印證了項(xiàng)目設(shè)計(jì)和實(shí)現(xiàn)的可行性。Nutch爬蟲(chóng)的可擴(kuò)展性和靈活性有很重要的意義。在異構(gòu)數(shù)據(jù)的融合上,所設(shè)計(jì)的自動(dòng)去重機(jī)制使爬蟲(chóng)在工作中對(duì)于相同地址不做重復(fù)爬取,從源頭上避免了數(shù)據(jù)的重復(fù)。設(shè)計(jì)的提取頁(yè)面信息模塊,能準(zhǔn)確找出網(wǎng)頁(yè)中展示的信息,關(guān)鍵詞匹配模塊,可以根據(jù)關(guān)鍵詞語(yǔ)義有效匹配出所要收集的信息,高效準(zhǔn)確。方便快捷的檢索能力,極大地方便了用戶,為其帶來(lái)了極好的體驗(yàn)。
將爬蟲(chóng)技術(shù)與其他它有其它技術(shù)相結(jié)合,更好地服務(wù)生活,將是接下來(lái)研究的目標(biāo)。