(山西管理職業(yè)學(xué)院,山西臨汾市 041051)
網(wǎng)絡(luò)中的冗余信息過多,用戶閱讀不同的信息需要在不同站點(diǎn)之間頻繁切換,這無形中增加了獲取新聞的難度,也增加了時(shí)間成本。
因此需要構(gòu)建一個新聞聚合系統(tǒng)從多個來源收集新聞,并以特定的格式進(jìn)行匯總。新聞聚合系統(tǒng)中的新聞數(shù)據(jù)需要通過網(wǎng)絡(luò)爬蟲來獲取,這其中包括web爬蟲、CMS、API、web爬蟲調(diào)度器和socket服務(wù)器的實(shí)現(xiàn)等。
網(wǎng)絡(luò)爬蟲是一個特定的機(jī)器人,是一種按照一定的規(guī)則,自動地抓取網(wǎng)絡(luò)信息的程序或腳本。目前主要有以下幾個比較實(shí)用的工具可以用來抓取網(wǎng)站并提取其內(nèi)容:
(1)Scrapy
Scrapy是一個用Python編程語言編寫的web爬蟲框架,Scrapy支持網(wǎng)頁抓取和頁面提取。
(2)BeautifulSoup
BeautifulSoup是用Python編程語言編寫的HTML解析器,可以用來從網(wǎng)頁中提取內(nèi)容,BeautifulSoup不能單獨(dú)用作網(wǎng)絡(luò)爬蟲。
(3)Link Grabber
Link Grabber是一個用Python編程語言編寫的庫,可以用來從網(wǎng)頁中提取統(tǒng)一資源定位器(URL),它有附加的功能,可以在錨標(biāo)記內(nèi)提取文本。
衡量網(wǎng)絡(luò)爬蟲的性能應(yīng)從以下指標(biāo)來考量:爬行能力(HTML解析器是否可以在安裝時(shí)自行抓取Web頁面)和處理能力(HTML解析器是否可以解析格式復(fù)雜的HTML頁面)。
表1 爬蟲的比較
Web應(yīng)用程序框架應(yīng)從以下兩個方面進(jìn)行比較:速度(在接收客戶端請求時(shí),框架返回響應(yīng)的時(shí)間等)和性能(內(nèi)置的功能,如庫、框架模板等)。
表2Web應(yīng)用程序框架的比較
基于Web應(yīng)用程序框架以及網(wǎng)絡(luò)爬蟲的比較,我們將使用Laravel框架作為其web應(yīng)用框架和BeautifulSoup作為其網(wǎng)絡(luò)爬蟲框架。選擇使用Laravel框架,是因?yàn)榕cCodeIgniter相比,它使用了更現(xiàn)代的體系結(jié)構(gòu)和PHP7特性,它也有一個與新聞聚合系統(tǒng)的發(fā)展相關(guān)的功能,即ORM。使用Laravel創(chuàng)建API也非常簡單,因?yàn)樗哂懈呒壍穆酚珊蛦卧獪y試功能。
對網(wǎng)絡(luò)爬蟲來說,選擇使用BeautifulSoup作為網(wǎng)絡(luò)爬蟲,因?yàn)榕cLink Grabber相比,BeautifulSoup不是一個復(fù)雜的框架。此外,截止到2017年5月,Link Grabber的開發(fā)已經(jīng)停滯了幾個月。而BeautifulSoup性能較高,可用于解析格式復(fù)雜的HTML頁面。此外,它還可以利用附加的庫來快速和靈活地解析HTML。如圖1展示了新聞聚合系統(tǒng)的概況,因篇幅所限,這篇論文只涵蓋了方框內(nèi)2的部分。
圖1 系統(tǒng)概況
系統(tǒng)后端構(gòu)架如圖2所示,每個實(shí)體都有自己的功能來支持后端系統(tǒng)的操作,每個模塊具體功能如下:
(1)Laravel框架是一個PHP框架,它可以用來托管應(yīng)用程序的CMS,以及為移動客戶端提供API,laravel框架主要將應(yīng)用程序數(shù)據(jù)存儲在MySQL數(shù)據(jù)庫中,它還能夠?qū)⑼ㄖ獢?shù)據(jù)通過Redis服務(wù)器發(fā)送到Socket服務(wù)器,從而向用戶發(fā)送通知。
(2)Laravel REST API是Laravel框架的一個組件,REST API被用作移動客戶端與框架之間的接口。
(3)Python新聞爬蟲用于從各種來源檢索Web頁面數(shù)據(jù),并提取要分析的內(nèi)容并將其存儲到MySQL數(shù)據(jù)庫中。要分析新聞文章,爬蟲會通過向AI發(fā)送一個HTTP請求來發(fā)送數(shù)據(jù),分析的結(jié)果將決定提取的消息是否會存儲到數(shù)據(jù)庫中,或者被丟棄。
(4)MySQL數(shù)據(jù)庫是用來存儲和檢索數(shù)據(jù)的數(shù)據(jù)庫系統(tǒng),之所以使用MySQL,是因?yàn)樵摽蚣苤С直镜豈ySQL數(shù)據(jù)庫的ORM系統(tǒng),Python新聞爬蟲還可以直接與MySQL系統(tǒng)通信,而不需要使用Laravel框架作為中間件。
(5)Redis服務(wù)器是內(nèi)存中的數(shù)據(jù)結(jié)構(gòu)系統(tǒng)。在本研究中,Redis被用作Laravel框架和套接服務(wù)器之間的消息代理。它還被REST API用作緩存驅(qū)動程序,以減少對MySQL數(shù)據(jù)庫的查詢。
(6)Socket服務(wù)是Node.JS的一個實(shí)例,用于為其客戶端提供WebSocket服務(wù),它用于從Laravel框架向連接的客戶端廣播數(shù)據(jù),其使用Socket.IO來進(jìn)行WebSocket實(shí)現(xiàn)。
圖2 后端構(gòu)架
這個項(xiàng)目采用了敏捷開發(fā)方法,鼓勵早期的軟件交付給客戶。在這種情況下,這允許研究人員為主要客戶端提供應(yīng)用程序的早期測試,主要客戶端是移動應(yīng)用程序和AI新聞分析器。我們還利用了測試驅(qū)動開發(fā)(TDD),測試驅(qū)動開發(fā)允許開發(fā)人員編寫包含模塊功能需求的測試,測試完成后,將創(chuàng)建一個函數(shù)或模塊來傳遞需求。它還確保代碼重構(gòu)或合并不會產(chǎn)生錯誤,因?yàn)榇a將在部署之前進(jìn)行測試,TDD用于本項(xiàng)目的API開發(fā)。
在API用例中有兩個角色(如下圖3所示):用戶和經(jīng)過身份驗(yàn)證的用戶。認(rèn)證的用戶之間唯一的區(qū)別是擁有一個有效的API令牌,有一些API端點(diǎn)只對身份驗(yàn)證的用戶具有獨(dú)占性。
(1)身份驗(yàn)證:用戶可試圖通過提供他們的憑證來驗(yàn)證系統(tǒng)的身份,一旦證書生效,系統(tǒng)將向用戶發(fā)出訪問令牌。訪問令牌的生命周期是有限的,可以在過期時(shí)間之前刷新,并在結(jié)束后很短的時(shí)間內(nèi)刷新。
(2)注冊:用戶可以通過提供數(shù)據(jù)向系統(tǒng)注冊,一旦用戶注冊,他們就可以嘗試對系統(tǒng)進(jìn)行身份驗(yàn)證。
(3)獲取新聞列表:任何用戶都可以通過搜索獲取新聞類別或獲取熱門新聞(頭條新聞)來檢索新聞列表,一旦他們獲得了新聞的列表,他們就可以通過訪問另一個端點(diǎn)獲取新聞的細(xì)節(jié)。
(4)獲取新聞文章:用戶可以獲取新聞的細(xì)節(jié)和評論。
(5)獲取另一個用戶數(shù)據(jù):用戶可以獲得另一個用戶數(shù)據(jù),比如他們的評論歷史和最新成果。
(6)內(nèi)容提交:經(jīng)過身份驗(yàn)證的用戶可以提交評論和喜好等內(nèi)容。他們可以對文章發(fā)表評論并回復(fù)評論等。
(7)個人數(shù)據(jù)管理:經(jīng)過身份驗(yàn)證的用戶可以獲取他們的個人數(shù)據(jù),如新聞閱讀歷史、新聞喜好列表、新聞首選項(xiàng)和通知設(shè)置,并且可以更新他們的新聞偏好和通知設(shè)置。
圖3 API用例
爬蟲的設(shè)計(jì)中需要設(shè)置日志文件,假如在Linux環(huán)境下沒有合適的日志文件,當(dāng)計(jì)劃任務(wù)開始后,命令行界面可能會被爬蟲程序的輸出淹沒。用戶可以通過設(shè)置來啟動爬蟲,例如,如果用戶想從新聞?wù)军c(diǎn)sina.com獲取數(shù)據(jù),他們可以設(shè)置sina作為程序參數(shù)啟動爬蟲。為了簡化調(diào)度任務(wù),爬蟲還可以設(shè)置掃描所有可用站點(diǎn),只要每個站點(diǎn)的配置文件是有效可用的。
爬蟲設(shè)計(jì)中需設(shè)置四個標(biāo)記:第一個標(biāo)記是限制標(biāo)記,如果用戶希望限制提取頁面的數(shù)量,則可以設(shè)置限制標(biāo)記;第二個標(biāo)記是調(diào)試標(biāo)記,如果希望程序在錯誤發(fā)生時(shí)立即退出,則可以設(shè)置此標(biāo)記,當(dāng)用戶正在為站點(diǎn)構(gòu)建配置文件時(shí),這很有用。第三個標(biāo)記是詳細(xì)標(biāo)記,如果用戶希望看到當(dāng)前爬行操作的進(jìn)度,則可以設(shè)置詳細(xì)標(biāo)記;第四個標(biāo)記是輸出標(biāo)記,用戶可以選擇抓取結(jié)果的輸出目標(biāo),例如,用戶可以選擇輸出到JSON文件中或數(shù)據(jù)庫中進(jìn)行進(jìn)一步的處理。
表3顯示了本項(xiàng)目的服務(wù)器需求:
后端應(yīng)用程序運(yùn)行在Raspberry Pi2上,并在表4中顯示了規(guī)范說明:
表3 服務(wù)器需求
表4Raspberry Pi2規(guī)范
API測試使用PHPUnit自動化測試,測試用例是根據(jù)移動應(yīng)用程序的要求編寫的,測試結(jié)果表明,所有的API端點(diǎn)都通過了測試用例。整個測試花費(fèi)了2.36分鐘,其中包括36個測試用例(包括錯誤測試)。為了加快測試的速度,測試使用存儲在內(nèi)存中的SQLite數(shù)據(jù)庫。每個測試都可能包括HTTP代碼判定、JSON結(jié)構(gòu)判定或JSON輸出判定。JSON結(jié)構(gòu)和JSON輸出判定之間的區(qū)別在于,在結(jié)構(gòu)判定上,它只判定JSON的整體結(jié)構(gòu)(不包括值),而輸出判定則希望判定準(zhǔn)確的值。
爬蟲通過SSH客戶機(jī)測試系統(tǒng)。接口采用命令行接口(CLI),可以在CLI中執(zhí)行的每個命令也可以由系統(tǒng)執(zhí)行,爬蟲的主要目的是定期從新聞網(wǎng)站獲取新聞。Crontab是類Unix操作系統(tǒng)中的任務(wù)調(diào)度程序,在此用于啟動預(yù)定的爬行會話。為了測試爬蟲的實(shí)際功能,使用以下命令直接將命令輸入到CLI:
以上命令包含兩個可選參數(shù)和一個必選參數(shù),處理結(jié)果可能根據(jù)目標(biāo)網(wǎng)站的內(nèi)容而有所不同。在詳細(xì)的測試結(jié)果中顯示找到了60個鏈接。但根據(jù)參數(shù)的設(shè)置,如果鏈接的總數(shù)超過10個,鏈接提取器模塊就會停止爬行。然而在詳細(xì)數(shù)據(jù)中顯示它只掃描了60個鏈接中的3個,這是因?yàn)榕老x會檢查數(shù)據(jù)庫中的鏈接,在限定時(shí)間內(nèi)已經(jīng)被爬行過的鏈接不再爬行。
為了增強(qiáng)爬蟲的性能,用戶可以通過添加配置文件或輸出程序來增加爬行器的功能。用戶可以向爬行器添加額外的配置文件,以允許爬蟲遍歷不同的網(wǎng)站,配置文件包含爬蟲程序的數(shù)據(jù),以便爬行器在網(wǎng)站上爬行,并對頁面數(shù)據(jù)進(jìn)行跟蹤;通過為爬行器創(chuàng)建一個提供程序類,用戶可以添加其他輸出提供程序,而不只是輸出到JSON,這樣便于用戶對不同類型的信息進(jìn)行更合理的利用。
本文研究的爬蟲不限于可以提取新聞?wù)军c(diǎn)的新聞,通過用戶設(shè)置自定義配置文件,還可以提取其他多種類型的網(wǎng)站數(shù)據(jù),并按照用戶的需求使用多種輸出方法來保存爬蟲提取的數(shù)據(jù)。爬蟲還有改進(jìn)空間,比如為了提高爬蟲的性能,添加作為守護(hù)進(jìn)程運(yùn)行的功能,這將使體系結(jié)構(gòu)不依賴于諸如Crontab之類的任務(wù)調(diào)度程序等。爬蟲本身是開源的,可以在此基礎(chǔ)上對爬蟲進(jìn)行進(jìn)一步的更新和完善。