單艷 張帆
(國家計算機網(wǎng)絡(luò)與信息安全管理中心新疆分中心 新疆維吾爾自治區(qū)烏魯木齊市 830017)
互聯(lián)網(wǎng)以及信息技術(shù)產(chǎn)業(yè)的快速發(fā)展,讓互聯(lián)網(wǎng)當中的數(shù)據(jù)變得繁雜多樣,網(wǎng)絡(luò)爬蟲本身是按照一定的規(guī)則,實現(xiàn)自動地抓取網(wǎng)頁的信息并且進行計算,網(wǎng)絡(luò)爬蟲的目的最主要在于將目標網(wǎng)頁當中的數(shù)據(jù)進行下載管理,方便用戶的使用,提高用戶的使用體驗,由于大數(shù)據(jù)時代的到來網(wǎng)絡(luò)爬蟲技術(shù)得到了快速的發(fā)展得到,用戶通過網(wǎng)絡(luò)爬蟲的爬取技術(shù)可以更加快捷的獲取到網(wǎng)絡(luò)數(shù)據(jù),便于進行數(shù)據(jù)挖掘。對于Python語言來說快捷簡單,目前的爬蟲框架和工具可以大幅度降低使用的門檻,保證表達式的使用,讓數(shù)據(jù)的抓取更加的穩(wěn)定。先目前,各大網(wǎng)站的反爬蟲機制已經(jīng)構(gòu)建完善,市面上存在的一部分爬蟲程序已經(jīng)滿足客戶的實際需求,所以一個能夠?qū)崿F(xiàn)網(wǎng)頁信息爬取的爬蟲項目也是時代發(fā)展的需要。本文最主要的研究內(nèi)容就是實現(xiàn)如何從目標網(wǎng)頁當中爬取自己所需要的信息,Pyhton作為一個學習較為簡單,簡單易上手的程序語言得到越來越多的重視,本文就主要選擇Python作為爬取技術(shù)的編寫軟件,使用其中較為成熟的庫,數(shù)據(jù)分配展示方面我們配合使用spring, mybats以及mvc三個主要框架實現(xiàn)數(shù)據(jù)的展示。
Python語言對開發(fā)的軟件一致性和質(zhì)量水準尤為重視,在使用Python語言進行開發(fā)之后,絕大部分人都不會再使用其他的開發(fā)語言,這就足以表明開發(fā)者們是有多執(zhí)迷于Python語言的應(yīng)用。初見Python語言的時候,人們會首先注意到它的可讀性功能,大部分人對于Python語言的定義就是,它是一種效率極高的腳本語言,這其實是和使用者的個人看法有關(guān),盡管它本身就具備著周期短、便于使用等諸多優(yōu)點,還能從容應(yīng)對所有的腳本語言工作,但它可不僅僅是一款功能強大的shell語言,甚至可以說是超出了控制語言的范疇,因為它在快速且靈活的開發(fā)模式中可以有出色的表現(xiàn),所以我們常說Python語言是多面性的。相比之下,Python語言的可讀性、可維護性等要比傳統(tǒng)腳本語言強大得多,這就是為什么許多人更愿意使用Python語言的根本原因。不僅如此,Python語言還具有著更好的軟件質(zhì)量、模塊數(shù)量多、支持標準庫、較強的可移植性、極高的開發(fā)效率、組件集成等諸多優(yōu)勢,得益于自身的強大功能,Python語言才可以在編程者的心中占據(jù)核心地位[1]。
對于python編程軟件來說scrapy是一個非常著名的爬取網(wǎng)站數(shù)據(jù)、提取結(jié)構(gòu)性數(shù)據(jù)的應(yīng)用框架,主要有scrapy Engine(引擎)、Scheduler(調(diào)度器)、Downloader(下載器)、Spider(爬蟲)、Item Pipeline(管道)五大組件,本次框架主要依靠downloader實現(xiàn)數(shù)據(jù)的抓取,我們只需要指定相應(yīng)的url,就可自動將抓取得到的內(nèi)容放置在item當中,客戶實現(xiàn)自定義的處理之后,scrapy框架封裝以及下載等過程,這樣將會大幅度加快軟件的編寫速度。scrapy enginer系統(tǒng)主要實現(xiàn)相關(guān)數(shù)據(jù)的通訊,信號的傳遞。scheduler系統(tǒng)主要實現(xiàn)對于SEd 下載之后發(fā)送給相關(guān)的管理請求得到報告數(shù)據(jù)返還。spiders主要是處理返回數(shù)據(jù)請求,提取試劑需要的數(shù)據(jù),交換引擎再次輸入到shceduler當中[2]。
因為scrapy需要一個較為固定明確目標網(wǎng)站,被首先處理的spider將會發(fā)送給引擎,引擎控制調(diào)度器將request加入其中,調(diào)度器處理完成之后再送回引擎。引擎將調(diào)度器送回的request分析之后轉(zhuǎn)送到下載器當中下載相關(guān)的信息,如果下載已經(jīng)失敗,引擎會保留之后傳回調(diào)度器,完成所有下載之后再繼續(xù)下載相關(guān)數(shù)據(jù)。
根本頁面的實際代碼我們可以知道,書單當中的信息卸載classs當中的mod book list當中的div其中存儲,在這些dl標簽當中的都是一個主題書當中的實際信息,我們需要的信息除非評價之后還需要簽訂dd標簽當中,評價的人數(shù)信息頁面當中,也就是實現(xiàn)超鏈接,按照相關(guān)的方法實現(xiàn)代碼的定位。
在實際檢測爬蟲軟件的時候需要構(gòu)建URL進行請求的時候,我們需要對于請求的狀態(tài)碼進行檢測分析。我們在進行爬取的時候需要遇到網(wǎng)站被封閉IP模式下,需要返回reponse的狀態(tài)碼需要分析,但是scrapy框架體系需要忽視,但是在scrapy庫模式需要對于狀態(tài)碼需要達到200-300請求處理分析。我們需要實現(xiàn)手動添加相關(guān)的代碼,這樣我們就可以判斷是否穩(wěn)定,最后實現(xiàn)相關(guān)的抓取分析。
MYSQL數(shù)據(jù)庫是一種具有小型關(guān)系型數(shù)據(jù)庫的管理系統(tǒng)。由于它具備體積小、運行速度快、研發(fā)成本低、開放源代碼等諸多優(yōu)勢,所以在各類中小型網(wǎng)站中得到了極為廣泛的普及和應(yīng)用。對于本次數(shù)據(jù)庫當中使用的mysql數(shù)據(jù)庫,需要進行pymysql驅(qū)動進行鏈接數(shù)據(jù)庫系統(tǒng),讀取相關(guān)的信息展示在相關(guān)的頁面當中,本文主要使用java當中的spring以及sprng mvc和mybatis作為主要的構(gòu)建頁面[3]。
現(xiàn)階段已經(jīng)出現(xiàn)的爬蟲,可以為我們提供豐富的開發(fā)經(jīng)驗、相關(guān)注意事項等。本次我們將豆瓣網(wǎng)作為研究對象,目的是對該網(wǎng)站上讀書標簽下的圖書進行爬取,同時根據(jù)該圖書的評分完成順序儲存。
首先,我們通過火狐瀏覽器進入豆瓣網(wǎng)中,隨便選擇一個有關(guān)主題的圖書頁面,單擊鼠標左鍵將其打開。在更換主題過程中,我們發(fā)現(xiàn)豆瓣網(wǎng)的URL具有一定的規(guī)律性。
對URL的轉(zhuǎn)換規(guī)律進行總結(jié)后得出:tag后面就是目標主題,類型資源緊隨其后,比如在看到book、source時,它們分別顯示的是圖書和各種資源。
其次,我們看到豆瓣網(wǎng)站的圖書頁面都是分頁的,而且單個頁面展示的資源數(shù)量為15個。將第2頁打開,可以看到頁面的URL出現(xiàn)了很大改變。
到這里,本文可以確認頁面URL的變化規(guī)律是:將頁面打開時,因為是第1頁,start參數(shù)顯示0,故而不顯示。進入第2頁后,start單次增加15,說明每一頁展示的資源數(shù)量就是15個。
將目標網(wǎng)站的URL變化模式確定下來后,接下來我們就要對網(wǎng)站中爬蟲內(nèi)容所處的位置進行分析。當前的目標信息包括書名、作者、評分、出版社和評價人數(shù)這5個。通過火狐瀏覽器進入豆瓣網(wǎng)的頁面,把目標網(wǎng)站找出來,按下F12鍵,隨后對頁面的源代碼進行分析,就能將所需信息的CSS代碼找出。本次我們將與南京有關(guān)的圖書假設(shè)為查找目標,結(jié)合火狐瀏覽器給到的信息,圖書與CSS關(guān)鍵代碼相互對應(yīng)。
從頁面的源代碼來看,書單的全部信息在class為mod booklist的div中都能夠找到。并且每一個dl標簽中,都有著與一本主題書相關(guān)的信息內(nèi)容。目標信息全部寫在dd標簽里,僅僅是評價人數(shù)沒有。但在其他頁面可以找到,即書名所在標簽的超鏈接位置。采用同樣的方法,可直接定位具體代碼。
由于在測試爬蟲的過程中,要持續(xù)構(gòu)造URL將請求發(fā)出,因此要監(jiān)測每一次請求后的狀態(tài)碼。在爬取期間,偶爾會有被該網(wǎng)站封IP的意外發(fā)生,這樣返回的reponse的狀態(tài)碼就會顯示403,但Scrapy會直接忽略這種狀態(tài)碼,原因在于它只處理在200到300以內(nèi)的狀態(tài)碼請求。所以,我們只能手動把handle-httpstatuslist=[403]這個代碼給加上去,從而通過判斷response.status==403,將CloseSpider異常排出,以此獲取結(jié)束抓取的功能。
本次研究中我們選擇了Mysql數(shù)據(jù)庫,使用PyMySQL驅(qū)動連接,才能實現(xiàn)對數(shù)據(jù)庫的操作。讀取展示模塊的功能是把數(shù)據(jù)庫里儲存的信息值在自己頁面上進行展示。本文在打造查詢頁面上,選用了Java中的三大框架,分別為MyBatis、SpringMvc和Spring[4]。
在首次運行爬蟲時我們發(fā)現(xiàn),只要爬取出的數(shù)據(jù)量在幾百條左右,就會陸續(xù)有許多像404的非正常狀態(tài)碼彈出。隨后進入豆瓣網(wǎng)中,發(fā)現(xiàn)以上的異常行為早已被網(wǎng)站所察覺,如果想要獲得正常的頁面,我們唯一的選擇就是進行登錄。出現(xiàn)這種情況的時候,說明被爬取的網(wǎng)站已經(jīng)檢測出來爬蟲腳本程序,由于在瀏覽特性方面與正常用戶存在差異,使得服務(wù)器自動封禁了檢測到的IP。
解決辦法:用User Agent偽裝后再來爬取目標網(wǎng)站,條件允許的話,可以再加一個隨機延時,使訪問瀏覽器行為更接近于正常用戶的操作。
由于本次爬取僅選擇和儲存了一個主題的書,因此在單表設(shè)計上是完全正常的。在同時爬取多個主題的書時,單表對于瀏覽所爬取的信息就不能起到幫助了。所以,當我們需要同時爬取多個主題的書時,應(yīng)該先把它轉(zhuǎn)移到Excel表格里進行存放,但要求一個單元格要與一跳爬取數(shù)據(jù)相互對應(yīng)。每個sheet頁都可以當做對應(yīng)主題爬取出的書的信息的存放空間。
按照評分數(shù)據(jù),由高到低進行順序排列和展示,可以讓我們?yōu)g覽目標的效率得到顯著提高。
本次研究是在豆瓣網(wǎng)中進行爬取。由于該網(wǎng)站里的靜態(tài)頁面占比較大,所以爬取難度要比其他的低很多。有時目標信息只有通過請求才能得到,例如應(yīng)用JavaScript生成、Ajax傳值等等。因此,我們要將火狐自帶的開發(fā)者工具運用起來,對請求中的參數(shù)進行查詢和瀏覽,緊接著再通過程序完成模擬過程。但是,部分網(wǎng)址的傳參已經(jīng)過加密處理,不能將目標參數(shù)請求給模擬構(gòu)造出來。對于該類網(wǎng)站,就得換個方法,比如通過selemium+phantomJS框架,用phantomJS將模擬人為的操作執(zhí)行下去,獲取JavaScript后,便具備了觸發(fā)頁面的條件。從表單數(shù)據(jù)的填寫、提交一直到回滾頁面,都能進行模擬。在這套框架的應(yīng)用下,絕大部分的反爬蟲方案都被破除了[5]。
在研究的初期通過對研究內(nèi)容的文獻的整理,本人較為充分的利用了互聯(lián)網(wǎng)文獻資料和圖書館資源,對基于Python的網(wǎng)頁信息爬取技術(shù)進行了較為全面的學習和研究,同時整理收集了大量Python的網(wǎng)頁信息爬取技術(shù)研究的相關(guān)資料,并且思考分析Python的網(wǎng)頁信息爬取技術(shù)研究當中容易出現(xiàn)的問題等,通過這些資料的整理和對前人的研究成功進行比較和借鑒,全面的總結(jié)了現(xiàn)有的文獻資料,得出了我國網(wǎng)頁信息爬取研究領(lǐng)域的最新觀點,實現(xiàn)了研究的現(xiàn)實性和實踐性。本文主要是對Python框架下基于主題的數(shù)據(jù)爬取技術(shù)研究與實現(xiàn)進行研究,通過爬蟲程序的實現(xiàn),來爬取目標網(wǎng)站的所需數(shù)據(jù),從而達到對Python開發(fā)相關(guān)步驟的充分了解及初步掌握。從程序編寫結(jié)束爬取數(shù)據(jù)出現(xiàn)IP被網(wǎng)站封禁的情況,到逐步優(yōu)化程序,能夠?qū)崿F(xiàn)在本地存儲爬取的信息,說明本文的研究目標已經(jīng)基本達成了。
經(jīng)過此次開發(fā)爬蟲程序,我們發(fā)現(xiàn)需要完善的部分還有許多。例如:在數(shù)據(jù)量較大時,爬蟲爬取的速度會明顯減慢,可嘗試用分布式的爬蟲進行爬取,有利于工作效率的提高。