左衛(wèi)剛
(山西管理職業(yè)學(xué)院,山西臨汾 041051)
新聞在社會(huì)發(fā)展中起著至關(guān)重要的作用,大多數(shù)人每天閱讀新聞,以確保能掌握最新的信息和趨勢(shì)。人們?cè)谖蘸屠斫庑畔⒅?,?huì)把其作為意識(shí)形態(tài)決策的參考。隨著科學(xué)技術(shù)的進(jìn)步,新聞在全球范圍內(nèi)傳播速度加快。使用互聯(lián)網(wǎng),知識(shí)、觀念、娛樂(lè)和新聞等信息,都可以很容易地被傳播。然而,網(wǎng)絡(luò)中的冗余新聞信息過(guò)多,用戶閱讀不同信息時(shí)需要在不同站點(diǎn)之間頻繁切換,這無(wú)形中增加了獲取新聞的難度,也增加了時(shí)間開(kāi)銷。
因此需要構(gòu)建一個(gè)新聞聚合系統(tǒng),從多個(gè)來(lái)源收集新聞,并以特定的格式進(jìn)行匯總。新聞聚合系統(tǒng)中的新聞數(shù)據(jù)需要通過(guò)網(wǎng)絡(luò)爬蟲來(lái)獲取,其中包括網(wǎng)絡(luò)爬蟲、CMS、API、網(wǎng)絡(luò)爬蟲調(diào)度器和socket服務(wù)器的實(shí)現(xiàn)等。
網(wǎng)絡(luò)爬蟲是一個(gè)特定的機(jī)器人,一種按照一定規(guī)則自動(dòng)抓取網(wǎng)絡(luò)信息的程序或腳本。目前主要有以下幾個(gè)比較實(shí)用的工具可以用來(lái)抓取網(wǎng)站并提取其內(nèi)容。
2.1.1 Scrapy
Scrapy是采用Python開(kāi)發(fā)的一個(gè)簡(jiǎn)單易用的網(wǎng)站內(nèi)容抓取框架,用于抓取web站點(diǎn)并從頁(yè)面中提取結(jié)構(gòu)化的數(shù)據(jù)。Scrapy用途廣泛,可用于數(shù)據(jù)挖掘、監(jiān)測(cè)等。
2.1.2 BeautifulSoup
BeautifulSoup是用Python編程語(yǔ)言編寫的HTML解析器,可以用來(lái)從網(wǎng)頁(yè)中提取內(nèi)容,BeautifulSoup不能單獨(dú)用作網(wǎng)絡(luò)爬蟲。
2.1.3 Link Grabber
Link Grabber是一個(gè)用Python編程語(yǔ)言編寫的庫(kù),可以用來(lái)從網(wǎng)頁(yè)中提取統(tǒng)一資源定位器(URL),具有附加的功能,可以在錨標(biāo)記內(nèi)提取文本。
衡量網(wǎng)絡(luò)爬蟲的性能應(yīng)從以下兩個(gè)指標(biāo)來(lái)考量:爬行能力(HTML解析器是否可以在安裝時(shí)自行抓取web頁(yè)面)和處理能力(HTML解析器是否可以解析格式復(fù)雜的HTML頁(yè)面),如表1所示。
表1 網(wǎng)絡(luò)爬蟲的比較
Web應(yīng)用程序框架應(yīng)從以下兩個(gè)方面進(jìn)行比較:速度(在接收客戶端請(qǐng)求時(shí),框架返回響應(yīng)的時(shí)間等)和性能(內(nèi)置的功能,如庫(kù)、框架模板等),如表2所示。
表2 Web應(yīng)用程序框架的比較
圖1 系統(tǒng)概況
基于上文比較,將使用Laravel框架作為其web應(yīng)用框架,將BeautifulSoup作為其網(wǎng)絡(luò)爬蟲框架。選擇使用Laravel框架,是因?yàn)榕cCodeIgniter相比,Laravel框架使用了更現(xiàn)代的體系結(jié)構(gòu)和PHP7特性,Laravel也有一個(gè)與新聞聚合系統(tǒng)的發(fā)展相關(guān)的功能,即ORM。使用Laravel創(chuàng)建API也非常簡(jiǎn)單,因?yàn)長(zhǎng)aravel具有更高級(jí)的路由和單元測(cè)試功能。
對(duì)網(wǎng)絡(luò)爬蟲來(lái)說(shuō),可選擇使用BeautifulSoup作為網(wǎng)絡(luò)爬蟲,因?yàn)榕cLink Grabber相比,BeautifulSoup不是一個(gè)復(fù)雜的框架。此外,截止到2017年5月,Link Grabber的開(kāi)發(fā)已經(jīng)停滯了幾個(gè)月。而B(niǎo)eautifulSoup性能較高,可用于解析格式復(fù)雜的HTML頁(yè)面。此外,BeautifulSoup還可以利用附加的庫(kù)來(lái)快速和靈活地解析HTML頁(yè)面。圖1展示了新聞聚合系統(tǒng)的概況,本文只涵蓋了方框內(nèi)(2.后端)部分。
圖2 后端構(gòu)架
系統(tǒng)后端構(gòu)架如圖2所示,每個(gè)實(shí)體都有自己的功能來(lái)支持后端系統(tǒng)的操作,每個(gè)模塊具體功能如下:
(1)Laravel框架是一個(gè)PHP框架,它可以用來(lái)托管應(yīng)用程序的CMS,為移動(dòng)客戶端提供API,laravel框架主要將應(yīng)用程序數(shù)據(jù)存儲(chǔ)在MySQL數(shù)據(jù)庫(kù)中,還能夠?qū)⑼ㄖ獢?shù)據(jù)通過(guò)Redis服務(wù)器發(fā)送到Socket服務(wù)器,從而向用戶發(fā)送通知。
(2)Laravel REST API是Laravel框架的一個(gè)組件,REST API被用作移動(dòng)客戶端與框架之間的接口。
(3)Python新聞爬蟲用于從各種來(lái)源檢索web頁(yè)面數(shù)據(jù),提取要分析的內(nèi)容并將其存儲(chǔ)到MySQL數(shù)據(jù)庫(kù)中。分析新聞文章時(shí),爬蟲通過(guò)向AI發(fā)送一個(gè)HTTP請(qǐng)求來(lái)發(fā)送數(shù)據(jù),由分析的結(jié)果決定提取的消息將被存儲(chǔ)到數(shù)據(jù)庫(kù)中還是被丟棄。
(4)MySQL數(shù)據(jù)庫(kù)是用來(lái)存儲(chǔ)和檢索數(shù)據(jù)的數(shù)據(jù)庫(kù)系統(tǒng),之所以使用MySQL,是因?yàn)樵摽蚣苤С直镜豈ySQL數(shù)據(jù)庫(kù)的ORM系統(tǒng),Python新聞爬蟲還可以直接與MySQL系統(tǒng)通信,而不需要使用Laravel框架作為中間件。
(5)Redis服務(wù)器是內(nèi)存中的數(shù)據(jù)結(jié)構(gòu)系統(tǒng)。在本研究中,Redis被用作Laravel框架和套接字服務(wù)器之間的消息代理。Redis還被REST API用作緩存驅(qū)動(dòng)程序,以減少對(duì)MySQL數(shù)據(jù)庫(kù)的查詢。
(6)Socket服務(wù)是Node.JS的一個(gè)實(shí)例,用于為其客戶端提供WebSocket服務(wù),Socket用于從Laravel框架向連接的客戶端廣播數(shù)據(jù),其使用Socket.IO來(lái)進(jìn)行WebSocket實(shí)現(xiàn)。
項(xiàng)目采用敏捷開(kāi)發(fā)方法,敏捷方法非常適合這個(gè)項(xiàng)目,因?yàn)樵摲椒ü膭?lì)將早期的軟件交付給客戶。在這種情況下,允許研究人員為主要客戶端提供應(yīng)用程序的早期測(cè)試,主要客戶端是移動(dòng)應(yīng)用程序和AI新聞分析器。我們還利用了測(cè)試驅(qū)動(dòng)開(kāi)發(fā)(TDD),允許開(kāi)發(fā)人員編寫包含模塊功能需求的測(cè)試,測(cè)試完成后,將創(chuàng)建一個(gè)函數(shù)或模塊來(lái)傳遞需求,這確保了代碼重構(gòu)或合并不產(chǎn)生錯(cuò)誤,因?yàn)榇a將在部署之前進(jìn)行測(cè)試,TDD用于本項(xiàng)目的API開(kāi)發(fā)。
在API用例中有兩個(gè)角色:普通用戶和認(rèn)證用戶,兩者之間唯一的區(qū)別是認(rèn)證用戶擁有一個(gè)更為有效的API令牌,有一些API端點(diǎn)只針對(duì)認(rèn)證用戶開(kāi)放。用戶通過(guò)提供數(shù)據(jù)進(jìn)行系統(tǒng)注冊(cè),注冊(cè)成功后登錄系統(tǒng),系統(tǒng)會(huì)根據(jù)用戶所屬的系統(tǒng)身份為其發(fā)放相應(yīng)的訪問(wèn)令牌。所有用戶登錄系統(tǒng)后均可通過(guò)設(shè)置新聞?lì)悇e等參數(shù)來(lái)獲取相應(yīng)的新聞列表,以及對(duì)應(yīng)的具體內(nèi)容和相關(guān)的評(píng)論回復(fù)信息,認(rèn)證用戶可對(duì)獲取的新聞進(jìn)行評(píng)論和回復(fù)。除此之外,認(rèn)證用戶還可獲取個(gè)人數(shù)據(jù),如新聞閱讀歷史、新聞喜好列表、新聞首選項(xiàng)和通知設(shè)置,并能夠更新新聞偏好和通知設(shè)置等。
爬蟲設(shè)計(jì)需要設(shè)置日志文件,假如在Linux環(huán)境下沒(méi)有合適的日志文件,當(dāng)計(jì)劃任務(wù)開(kāi)始后,命令行界面可能會(huì)被爬蟲程序的輸出淹沒(méi)。用戶可以通過(guò)設(shè)置來(lái)啟動(dòng)爬蟲,例如,如果用戶想從新聞?wù)军c(diǎn)sina.com獲取數(shù)據(jù),可以設(shè)置sina作為程序參數(shù)啟動(dòng)爬蟲。為了簡(jiǎn)化調(diào)度任務(wù),還可以設(shè)置爬蟲掃描所有可用站點(diǎn),只要每個(gè)站點(diǎn)的配置文件是有效可用的。
爬蟲設(shè)計(jì)需設(shè)置四個(gè)標(biāo)記:第一個(gè)標(biāo)記是限制標(biāo)記,如果用戶希望限制提取頁(yè)面的數(shù)量,則可以設(shè)置限制標(biāo)記;第二個(gè)標(biāo)記是調(diào)試標(biāo)記,如果用戶希望程序在錯(cuò)誤發(fā)生時(shí)立即退出,則可以設(shè)置調(diào)試標(biāo)記,這有助于用戶為站點(diǎn)構(gòu)建配置文件;第三個(gè)標(biāo)記是詳細(xì)標(biāo)記,如果用戶希望看到當(dāng)前爬行操作進(jìn)度,則可以設(shè)置詳細(xì)標(biāo)記;第四個(gè)標(biāo)記是輸出標(biāo)記,用戶可以選擇抓取結(jié)果的輸出目標(biāo),例如,用戶可以選擇輸出到JSON文件中還是在數(shù)據(jù)庫(kù)中再對(duì)數(shù)據(jù)進(jìn)行進(jìn)一步的處理。
為了增強(qiáng)爬蟲的性能,用戶可以通過(guò)添加配置文件或輸出程序來(lái)解決。用戶向爬行器添加額外的配置文件,以允許爬蟲遍歷不同的網(wǎng)站,并對(duì)頁(yè)面數(shù)據(jù)進(jìn)行跟蹤。為便于對(duì)獲取到的不同類型的信息進(jìn)行更為有效的利用,用戶還可創(chuàng)建一個(gè)提供程序類,將結(jié)果輸出為除JSON以外的其他數(shù)據(jù)格式。
本項(xiàng)目的服務(wù)器需求如表3所示。
表3 服務(wù)器需求
由于經(jīng)濟(jì)性原因,將后端應(yīng)用程序運(yùn)行在Raspberry Pi2上,規(guī)范說(shuō)明如表4所示。
表4 Raspberry Pi2規(guī)范
在此使用PHPUnit進(jìn)行API測(cè)試,測(cè)試用例是根據(jù)移動(dòng)應(yīng)用程序的要求編寫的,測(cè)試結(jié)果表明,所有的API端點(diǎn)都通過(guò)了測(cè)試用例。整個(gè)測(cè)試花費(fèi)了2.36分鐘,其中包括36個(gè)測(cè)試用例(包括錯(cuò)誤測(cè)試)。為了加快測(cè)試速度,測(cè)試使用存儲(chǔ)在內(nèi)存中的SQLite數(shù)據(jù)庫(kù)。每個(gè)測(cè)試都可能包括HTTP代碼判定、JSON結(jié)構(gòu)判定或JSON輸出判定。JSON結(jié)構(gòu)判定和JSON輸出判定之間的區(qū)別在于前者只判定JSON的整體結(jié)構(gòu)(不包括值),而后者則判定準(zhǔn)確的值。
爬蟲通過(guò)SSH客戶機(jī)測(cè)試系統(tǒng)。接口采用命令行接口(CLI),在CLI中執(zhí)行的每個(gè)命令也可以由系統(tǒng)執(zhí)行,爬蟲的主要目的是定期從新聞網(wǎng)站獲取新聞。Crontab是類Unix操作系統(tǒng)中的任務(wù)調(diào)度程序,在此用于啟動(dòng)預(yù)定的爬行會(huì)話。為了測(cè)試爬蟲的實(shí)際功能,使用以下命令直接將命令輸入到CLI。
python3 crawler.py ——limit 10 ——verbose detik
以上命令包含2個(gè)可選參數(shù)和1個(gè)必選參數(shù),處理結(jié)果可根據(jù)目標(biāo)網(wǎng)站的內(nèi)容而有所不同。命令中將鏈接總數(shù)的上限設(shè)置為10(此上限限定的數(shù)量不包括在限定時(shí)間范圍內(nèi)已經(jīng)被爬行過(guò)的鏈接)。如果爬行鏈接總數(shù)超過(guò)10,鏈接提取器模塊將會(huì)停止爬行。
本文研究的爬蟲不僅僅局限于提取新聞?wù)军c(diǎn)的新聞,通過(guò)用戶設(shè)置自定義配置文件,還可以提取其它多種類型的網(wǎng)站數(shù)據(jù),并按照用戶需求使用多種輸出方法來(lái)保存所提取的數(shù)據(jù)。然而,爬蟲在性能上還有提升的空間,基于爬蟲本身是開(kāi)源的,開(kāi)發(fā)者可在本文基礎(chǔ)上對(duì)爬蟲做進(jìn)一步的更新和完善。
長(zhǎng)春師范大學(xué)學(xué)報(bào)2018年12期