嚴(yán)斐 肖璞
摘 要: 如今上網(wǎng)查詢和購物已經(jīng)成為人們的生活必需。由于在很多系統(tǒng)上查看商品或資源需要點(diǎn)擊跳轉(zhuǎn)多個(gè)頁面,隨著瀏覽時(shí)間的增加,經(jīng)常會(huì)出現(xiàn)眼花繚亂的感覺。若只為用戶呈現(xiàn)必要的數(shù)據(jù),必將提高篩選資源的效率。文章使用Python語言結(jié)合目前流行的Spring MVC框架來爬取目標(biāo)網(wǎng)站的數(shù)據(jù),設(shè)計(jì)了數(shù)據(jù)爬取模塊和數(shù)據(jù)展示模塊,實(shí)現(xiàn)了基于主題的爬蟲框架。通過爬取實(shí)驗(yàn)與結(jié)果測(cè)試,成功爬取到了目標(biāo)網(wǎng)站的數(shù)據(jù)并展示到自己的頁面上,實(shí)現(xiàn)了預(yù)期的目標(biāo)。
關(guān)鍵詞: 數(shù)據(jù)爬取; 基于主題;爬蟲; SpringMVC
中圖分類號(hào):TP311 文獻(xiàn)標(biāo)志碼:A 文章編號(hào):1006-8228(2018)11-10-04
Abstract: Nowadays, online enquiries and shopping have become the indispensable of people's daily life. Because viewing goods or resources on many systems requires clicking and jumping over multiple pages, it is often a dazzling feeling as browsing time increases. If only provide users with the necessary data, the efficiency of screening resources will certainly be improved. Combining with the popular Spring MVC framework, this paper uses Python language to crawl the data of the target website, designs the data crawling module and data display module, and implements the theme-based crawler framework. The crawling experiment and the test result show that, the data of the target website is crawled and displayed on its own page, and the expected goal is achieved.
Key words: data crawling; theme-based; crawler; Spring MVC
0 引言
互聯(lián)網(wǎng)的快速發(fā)展使得互聯(lián)網(wǎng)的數(shù)據(jù)變得又多又雜,人們無法在一張頁面上獲取到盡可能多的數(shù)據(jù)。因此,爬取不同網(wǎng)頁上的更多的數(shù)據(jù)已經(jīng)成為了一種趨勢(shì)。本文的研究目的就是盡可能多的從目標(biāo)網(wǎng)站上爬取自己想要的信息來提高獲取有用信息的效率。
隨著技術(shù)的不斷發(fā)展,各個(gè)網(wǎng)站的反爬蟲機(jī)制也日漸成熟,市面上所存在的一些爬蟲程序已經(jīng)不能正確的爬取到用戶想要的信息。因此,一個(gè)能正確爬取數(shù)據(jù)的爬蟲項(xiàng)目也是市場(chǎng)上所需要的[1]。
本文研究的內(nèi)容是如何從目標(biāo)網(wǎng)頁上爬取自己想要的信息。目前Python作為一門易學(xué)習(xí),易入手的編程語言受到越來越多程序員的青睞。本文選用Python作為爬取技術(shù)的編程語言,調(diào)用其中較成熟的庫如BeautifulSoup庫,Requests庫和Scrapy庫,再配合Mysql數(shù)據(jù)庫。數(shù)據(jù)展示方面配合Spring、MyBatis、Spring MVC三大框架將爬取到的數(shù)據(jù)展示到所需的頁面上。
1 爬蟲框架介紹
1.1 Scrapy庫介紹
Scrapy是一個(gè)Python著名的爬蟲框架,如圖1所示。該框架使用了Downloader抓取數(shù)據(jù),只需要指定被抓取的url,將抓取的內(nèi)容放進(jìn)Item Pipeline,由客戶進(jìn)行自定義的處理。Scrapy框架封裝了下載和調(diào)度等過程,方便了爬蟲的編寫。
⑴ Scrapy Engine:負(fù)責(zé)Spider,ItemPipline,Downloader,Scheduler中的通訊,信號(hào),數(shù)據(jù)傳遞等。
⑵ Scheduler:負(fù)責(zé)接收引擎發(fā)送過來的Request請(qǐng)求,按照一定的順序整理,入隊(duì)再還給引擎。
⑶ Downloader:下載Scrapy Engine發(fā)送的所有的request請(qǐng)求并將獲取到的Responses還給Scrapy Engine,由Spider來處理。
⑷ Spiders:負(fù)責(zé)處理所有的Response請(qǐng)求并分析數(shù)據(jù),提取Item需要的數(shù)據(jù),將后繼的URL交給引擎并再次進(jìn)入Scheduler。
⑸ ItemPipeline:負(fù)責(zé)處理Spider獲取到的Item,進(jìn)行后期處理。
1.2 Scrapy框架的運(yùn)作流程
⑴ 需要明確一個(gè)目標(biāo)網(wǎng)站,第一個(gè)將要被處理的URL將會(huì)由Spider發(fā)送給引擎(Scrapy Engine)。
⑵ 引擎(Scrapy Engine)將會(huì)通知調(diào)度器(Scheduler)將一些request請(qǐng)求入隊(duì)。調(diào)度器(Scheduler)處理好之后再還給引擎(Scrapy Engine)。
⑶ 引擎(Scrapy Engine)將通知下載器(Downloader)下載request請(qǐng)求中需要的信息。如果下載失敗,引擎(Scrapy Engine)將會(huì)通知調(diào)度器記錄,等全部完成后再次下載。
⑷ 下載完的內(nèi)容將返回給Spider由用戶自定義處理。此時(shí),Spider會(huì)獲取以下信息:一是需要跟進(jìn)的URL,二是獲取到的Item數(shù)據(jù)。
⑸ 引擎(Scrapy Engine)通知管道(Item Pipeline)處理獲取到的Item數(shù)據(jù)。同時(shí)還要通知調(diào)度器(Scheduler)跟進(jìn)URL。
最后循環(huán)工作,直到獲取完所有需要的數(shù)據(jù)結(jié)束工作。
1.3 BeautifulSoup庫與Requests庫
BeautifulSoup庫與Requests庫作為Python爬蟲最常用的兩個(gè)庫現(xiàn)已被開發(fā)者廣泛使用。BeautifulSoup庫是一中靈活方便的解析庫,它處理高效并且支持許多的解析器。我們只需導(dǎo)入該庫,直接調(diào)用其中的函數(shù)就可以找到所需要的信息。對(duì)于一些前端頁面代碼較為復(fù)雜的網(wǎng)站,BeautifulSoup庫可以很大程度地減少程序員編寫代碼的時(shí)間。
Requests是一個(gè)很實(shí)用的HTTP客戶端庫,編寫爬蟲類的項(xiàng)目基本都會(huì)使用到它。它具有一些很好的特性:第一,給目標(biāo)URL后添加參數(shù)時(shí)不需要手動(dòng)構(gòu)造新的URL,方便且避免了許多低級(jí)錯(cuò)誤。第二,Requests庫中的session函數(shù)可以自動(dòng)保存cookies,設(shè)置請(qǐng)求參數(shù),下次請(qǐng)求時(shí)可以自動(dòng)帶上請(qǐng)求的參數(shù)。第三,Requests庫支持流式上傳,支持上傳較大的文件或者數(shù)據(jù)而無需先把它們放進(jìn)內(nèi)存中。
2 目標(biāo)網(wǎng)站爬蟲設(shè)計(jì)
2.1 目標(biāo)網(wǎng)站的確定與進(jìn)入
目前現(xiàn)有的爬蟲能帶給我們很多的開發(fā)經(jīng)驗(yàn)與注意事項(xiàng)[2-6]。本次研究選取的目標(biāo)網(wǎng)站是對(duì)爬蟲比較友好的豆瓣網(wǎng),主題是爬取豆瓣網(wǎng)上讀書標(biāo)簽下的圖書并且按照該圖書的評(píng)分依次存儲(chǔ)下來。
首先,我們使用火狐瀏覽器打開豆瓣網(wǎng),任選一個(gè)關(guān)于主題的圖書頁面點(diǎn)擊進(jìn)入。嘗試更換主題,我們發(fā)現(xiàn)豆瓣網(wǎng)的URL是有規(guī)律的。如圖2和圖3所示。
基本確定URL的改變規(guī)律為:tag后面為所需要的主題,主題后面緊跟著類型資源,如果是book就顯示圖書,如果是source就是顯示的各種資源。
其次,可以發(fā)現(xiàn)豆瓣網(wǎng)站圖書頁面是分頁的并且每個(gè)頁面只展示15個(gè)資源。點(diǎn)擊第二頁,發(fā)現(xiàn)頁面的URL發(fā)生了如下變化,具體變化如圖4和圖5所示。
至此,本文基本確定了頁面URL的變化規(guī)律,首次進(jìn)入頁面時(shí)由于是第一頁所以start參數(shù)為0,不顯示。第二頁開始start每次增加15代表每頁只展示15個(gè)資源。
2.2 信息匹配與檢索
確定了目標(biāo)網(wǎng)站的URL變化模式,下一步分析我們需要爬取內(nèi)容在網(wǎng)站中的位置?,F(xiàn)在的目標(biāo)信息為:書名,評(píng)分,評(píng)價(jià)人數(shù),作者與出版社。需要用火狐瀏覽器打開豆瓣頁面,找到目標(biāo)網(wǎng)站,按下F12,然后分析頁面的源代碼,找到目標(biāo)信息的CSS代碼。本次假設(shè)查找的目標(biāo)為關(guān)于南京的圖書,根據(jù)火狐瀏覽器所提供的信息,圖書信息對(duì)應(yīng)的CSS關(guān)鍵代碼如圖6所示。
根據(jù)頁面的源代碼得知:書單的所有信息都寫在了class為mod book-list的div中。其中每個(gè)dl標(biāo)簽都是一本關(guān)于主題書的信息。需要的信息除了評(píng)價(jià)人數(shù)以外,其他都寫在dd標(biāo)簽中。評(píng)價(jià)人數(shù)的信息在另外的頁面,也就是書名所在標(biāo)簽的超鏈接。按照同樣的方法進(jìn)行代碼的定位。
2.3 狀態(tài)碼的檢測(cè)
由于在測(cè)試爬蟲時(shí)需要不斷的構(gòu)造URL來進(jìn)行請(qǐng)求,所以需要對(duì)每次請(qǐng)求后的狀態(tài)碼進(jìn)行一個(gè)監(jiān)測(cè)[8]。當(dāng)進(jìn)行爬取時(shí)有時(shí)候會(huì)遇到被該網(wǎng)站封IP的情況,此時(shí)返回的reponse的狀態(tài)碼為403,但是Scrapy框架會(huì)將該情況忽視掉,因?yàn)镾crapy庫默認(rèn)是對(duì)狀態(tài)碼處于200-300之間的請(qǐng)求處理。因此,我們需要手動(dòng)添加代碼:handle_httpstatus_list=[403],這樣就能通過判斷response.status==403來拋出CloseSpider異常,最后結(jié)束抓取。
2.4 錄入與展示
本次數(shù)據(jù)庫選用的是Mysql數(shù)據(jù)庫,需要PyMySQL驅(qū)動(dòng)連接操作數(shù)據(jù)庫。讀取展示模塊就是將數(shù)據(jù)庫中存儲(chǔ)的信息值展示在自己的頁面上。本文選擇用Java中的Spring,SpringMvc,MyBatis三大框架搭建查詢頁面。查詢效果圖如圖7所示。
3 編寫爬蟲時(shí)遇到的問題
3.1 爬蟲被封禁
在第一次運(yùn)行爬蟲爬取了幾百條數(shù)據(jù)后,開始大量的出現(xiàn)不正常的狀態(tài)碼,如404。再當(dāng)人為打開豆瓣時(shí),發(fā)現(xiàn)網(wǎng)站已經(jīng)發(fā)現(xiàn)了我們的異常行為,并強(qiáng)制要求登錄,登錄以后才顯示正常的頁面[9]。這種情況說明所爬取的目標(biāo)網(wǎng)站已經(jīng)檢測(cè)到了我們的爬蟲,也就是我們的瀏覽特性與正常用戶不一樣,導(dǎo)致服務(wù)器將我們當(dāng)前的IP進(jìn)行封禁。
對(duì)此的解決方案就是采用User Agent偽裝對(duì)目標(biāo)網(wǎng)站進(jìn)行爬取,并加入隨機(jī)延時(shí)來更好的模擬訪問瀏覽器行為。
3.2 多主題爬取
由于此次爬取只選擇了一個(gè)主題的書進(jìn)行存儲(chǔ),所以單表設(shè)計(jì)沒有問題。當(dāng)對(duì)多個(gè)主題的書進(jìn)行爬取時(shí),單表不利于爬取信息的瀏覽。所以在對(duì)多個(gè)主題的書進(jìn)行爬取時(shí),可以將其存放至Excel表格中,每個(gè)單元格對(duì)應(yīng)的是一跳爬取數(shù)據(jù)。每個(gè)sheet頁則存放對(duì)應(yīng)主題爬取到的書的信息。
根據(jù)評(píng)分從高到低依次排序展示,使得我們能更有效的瀏覽所需信息。對(duì)應(yīng)的展示效果圖如圖8所示。
3.3 加密的傳參
本次選擇爬取的頁面是豆瓣網(wǎng)。豆瓣網(wǎng)內(nèi)大多數(shù)頁面都是靜態(tài)的,相對(duì)來說比較容易爬取。有時(shí)需要的信息必須通過請(qǐng)求獲取,比如使用Ajax傳值或者使用JavaScript生成。所以我們需要使用火狐自帶的開發(fā)者工具,查看請(qǐng)求中的參數(shù),然后使用程序進(jìn)行模擬。當(dāng)然,有些網(wǎng)站的傳參是加密過的,無法模擬構(gòu)造需要的參數(shù)請(qǐng)求。遇到這樣的網(wǎng)站,需要改變技術(shù),采用selenium+phantomJS框架,使用phantomJS來執(zhí)行js模擬人為的操作,觸發(fā)頁面的JavaScript腳本。從填寫表單數(shù)據(jù)到表單數(shù)據(jù)提交,再到回滾頁面,這些都可以模擬出來。利用這套框架,就可以解決大多數(shù)的反爬蟲策略[7]。
4 結(jié)束語
本文研究的是Python框架下基于主題的數(shù)據(jù)爬取技術(shù)研究與實(shí)現(xiàn),通過爬蟲程序的實(shí)現(xiàn),對(duì)目標(biāo)網(wǎng)站目標(biāo)數(shù)據(jù)進(jìn)行爬取,深入了解了Python開發(fā)的一系列步驟。從編寫完程序爬取數(shù)據(jù)時(shí)IP被網(wǎng)站封禁,到一步步優(yōu)化程序成功爬取信息保存到本地,實(shí)現(xiàn)了本次論文的研究目標(biāo)。
雖然本次爬蟲程序的開發(fā)工作結(jié)束,但還有很多地方需要改進(jìn)。比如,當(dāng)數(shù)據(jù)量過大,爬蟲爬取耗費(fèi)的時(shí)間會(huì)比較耗時(shí),可以嘗試改進(jìn)成分布式的爬蟲,這樣可以提升工作效率。
參考文獻(xiàn)(References):
[1] 管華.對(duì)當(dāng)今Python快速發(fā)展的研究與展望[J].信息系統(tǒng)工程,2015.12.
[2] 姜杉彪,黃凱林,盧昱江,張俊杰,曾志高,劉強(qiáng).基于Python的專業(yè)網(wǎng)絡(luò)爬蟲的設(shè)計(jì)與實(shí)現(xiàn)[J].企業(yè)科技與發(fā)展,2016.8.
[3] 孫立偉,何國輝,吳禮發(fā).網(wǎng)絡(luò)爬蟲技術(shù)的研究[J].電腦知識(shí)與技術(shù),2010.15.
[4] 成功,李小正,趙全軍.一種網(wǎng)絡(luò)爬蟲系統(tǒng)中URL去重方法的研究[J].中國新技術(shù)新產(chǎn)品,2014.12.
[5] 牛率仁.簡析主題網(wǎng)絡(luò)爬蟲搜索策略[J].電腦迷,2016.10.
[6] 陳琳,任芳.基于Python的新浪微博數(shù)據(jù)爬蟲程序設(shè)計(jì)[J].計(jì)算機(jī)技術(shù)與展,2007.3.
[7] 劉艷平,俞海英,戎沁.Python模擬登錄網(wǎng)站并抓取網(wǎng)頁的方法[J].微型電腦應(yīng)用,2015.2.