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