楊 健,陳 偉
(諸暨市公安局,浙江 紹興 311800)
隨著信息技術的發展,網絡數據成為一種重要資產,如何快速有效地提取和分析數據是目前該研究領域的熱點[1]。夏火松等[2]、云洋[3]應用Requests技術分別開發了商品評論、百度貼吧圖片爬蟲,優化了爬蟲算法,并為用戶提供了有效的信息參考。劉燦等[4]、WU等[5]基于Scrapy框架開發了教育新聞、Steam商店信息爬蟲,實現了個性化推薦、自動獲取游戲信息。潘洪濤[6]利用Selenium技術具有的自動化測試特性,設計與實現了一種多源統一爬蟲框架,可以面向多個網站數據源,以統一的接口形式實現數據抓?。辉S景賢等[7]安裝配套的Chrome WebDriver驅動,調用Selenium接口模擬人工自動點擊瀏覽器,繞過淘寶配置的反爬措施,成功爬取淘寶上的商品價格和名稱。上述研究工作使用Python多種爬蟲技術實現了相關業務需求,但均沒有探討技術區別和選用理由。
針對以上問題,本文介紹了基于Python的Requests、Scrapy和Selenium三種主流爬蟲技術,設計實現網絡爬蟲的程序框架。通過設計爬取“站長之家”網站簡歷數據的實驗案例,實現不同技術的環境配置、程序開發和并發性能等的比較。結果表明,不同的網絡爬蟲技術具有不同的優點和缺點,適用不同的業務場景,因此在開發方案選擇上要合理選用,以提升數據爬取的穩定性、準確性和工作效率。
使用Requests、Scrapy和Selenium技術開發的網絡爬蟲,由于抓取的原始數據格式包含HTML、XML和JSON,因此對目標數據的獲取要輔以其他技術解析并持久化保存。
Requests技術屬于爬蟲基礎性工具包,它模擬人輸入網址向服務器遞交網絡請求,實現自動爬取HTML網頁頁面信息的功能。根據HTTP協議對資源的六大操作方法,Requests配備對應的GET、POST、HEAD、PUT、PATCH、DELETE六個基礎方法和一個REQUEST通用方法,具有HTTP連接池自動化、持久Cookie會話、SSL認證等基本功能。
Selenium技術是一個基于Web應用程序且支持瀏覽器驅動的開源自動化測試框架,其運行過程就是一個可視化地模擬人輸入網址、滾動鼠標、點擊等動態的操作過程,能夠對Chrome、Firefox、IE等瀏覽器中的對象元素進行定位、窗口跳轉及結果比較等操作,具有執行網頁JS加載、Ajax動態異步等技術,能做到可見即可爬,支持Python、Java、C#主流編程語言二次開發。
Scrapy技術是一個網站數據爬取和結構性數據提取的應用框架,包含引擎、調度器、下載器、解析爬蟲、項目管道五個模塊和下載器、解析爬蟲兩個中間件。該技術框架已設計了爬蟲通用的數據和業務接口,方便根據業務需求聚焦爬取、解析、下載、存儲等操作。
網絡爬蟲爬取初始數據后需要進行解析,常用的技術如下:(1)Xpath庫,它能夠對特定數據進行定位,以更好地獲取特定元素,通常存儲在XML文檔中,在一定程度上起著導航作用。(2)RE正則表達式庫,它通過規定一系列的字符及符號來進行數據篩選,實現圖片、視頻和關鍵字的搜索,進而實現信息的爬取。(3)BS4庫,它運用HTML解析策略,把HTML源代碼重新進行格式化,方便使用者對其中的節點、標簽、屬性等進行操作,完成網站數據的抓取、篩選操作。(4)JSON庫,它是一種輕量級的數據交換格式,采用對象和數組的組合形式表示數據,用于將數據對象編碼為JSON格式進行輸出或存儲,再將JSON格式對象解碼為Python對象。
網絡爬蟲一旦啟動將采取定制、自動化模式爬取目標網頁的數據,首先從初始頁面的URL地址開始,通過向目標站點發送一個Web請求,等待服務器響應;然后獲取響應的頁面內容,可能包含HTML、JSON字符串、二進制等數據類型,根據響應網頁數據類型,輔助以用正則表達式等網頁解析庫進行解析,獲得目標數據;最后保存數據,將數據保存為文本格式或者保存至數據庫。如果目標數據涉及URL地址嵌套關聯,就要通過分析頁面中的其他相關URL,抓取新的網頁鏈接,反復循環,直至爬取、分析和獲取所有頁面內容。通用網絡爬蟲模型如圖1所示。

圖1 通用網絡爬蟲模型Fig.1 General web crawler model
本實驗使用Python 3.6.4版本作為開發環境,采用集成工具PyCharm 2020.1版本開發。爬蟲核心代碼如下:


本實驗以“站長之家”的簡歷欄目(https://sc.chinaz.com/jianli/)作為爬取數據目標,該網站簡歷欄目素材豐富,網頁包含JS、CSS、文字、圖片、文件等,網站robots協議允許所有網絡爬蟲訪問。實驗環境使用“聯想”的小新AIR-14 2020筆記本電腦(操作系統:Windows 10專業版;處理器:Intel酷睿i5,CPU運行頻率1.00 GHz;內存16 GB)和浙江大學華家池校區Wi-Fi網絡SCEZJU-GUEST。
實驗通過環境配置、代碼實現、單線程和多線程等維度,比較三種爬蟲技術的程序開發難易程度及耗時。為避免數據解析影響實驗結果,在耗時計算中剔除了第三方庫解析原始數據的時間,具體步驟如下。
Step1:安裝配置。根據Requests、Scrapy和Selenium技術的安裝要求及依賴包,配置環境和第三方插件。
Step2:準備工作。通過瀏覽器查看目標網頁,確定URL地址及翻頁參數。
Step3:獲取數據。向目標網頁發起請求,正常響應返回得到原始數據。
Step4:解析內容。通過Xpath庫解析獲取目標數據并在IDEA工具中打印。
Step5:變更URL翻頁參數,通過步驟1至步驟4中,分別進行單線程、多線程等實驗并記錄時間。
5.2.1 環境安裝、代碼開發比較
表1顯示了三種爬蟲技術的環境配置與開發實現對比信息。其中,Requests、Scrapy和Selenium包通過Python的pip命令安裝。在程序開發中,Requests、Scrapy網絡爬蟲在模擬訪問時要攜帶Headers請求頭,請求返回的響應不會執行獲取網頁中的JS動態代碼,無法得到由JS異步請求的網頁數據。開發Scrapy網絡爬蟲,程序代碼要按照框架自帶的引擎、調度器、下載器、解析爬蟲、項目管道等模塊要求開發,如果要調用爬蟲抓取的不同數據進行業務定制,技術實現不夠靈活。Selenium網絡爬蟲必須安裝配套的Webdriver驅動以調用本機瀏覽器,Selenium爬蟲通過本機瀏覽器模擬訪問網頁,因此代碼中不需要攜帶Headers請求頭。爬取網頁的JS動態代碼被瀏覽器執行,獲取的響應已包含JS異步請求數據,這是Requests、Scrapy技術無法實現的。

表1 環境配置與開發實現對比表Tab.1 Comparison table of environment configuration and development implementation
5.2.2 單線程運行下爬蟲性能分析
采用單線程爬取網頁實驗中,運行三種爬蟲程序,分別爬取目標網站網頁數量為10 頁、100 頁、500 頁和1,000 頁且運行3 次,記錄時間和計算平均值。表2顯示了三種爬蟲爬取頁面的耗時對比。經分析發現:(1)對同樣頁面數進行輪爬,三種爬蟲第1、2、3 次的爬取耗時差異不大,但三種爬蟲之間的爬取耗時對比差異較大。(2)Requests爬蟲的四輪實驗的平均每頁爬取時間為0.24 s、0.27 s、0.28 s和0.26 s,爬取速度比較穩定;Selenium爬蟲的四輪實驗的平均每頁爬取時間為1.08 s、1.47 s、1.64 s和1.42 s,當爬取的頁面數量較多時,平均爬取每頁的耗時多于爬取少量頁面的耗時,但總體速度比較穩定;Scrapy爬蟲的四輪實驗的平均每頁爬取時間為0.08 s、0.02 s、0.02 s和0.02 s,爬取每頁的平均耗時均不到0.1 s,速度極快且穩定。在單線程爬取實驗中,Scrapy爬蟲耗時最少、Selenium爬蟲耗時最多。(3)三種爬蟲爬取網頁數量為10 頁、100 頁、500 頁和1,000 頁的平均耗時接近線性遞增。從增量來看,Scrapy爬蟲耗時最少,Selenium爬蟲耗時最多,隨著爬取頁面數量的增加,三種爬蟲的爬取耗時差距逐漸增大,如圖2所示。

圖2 單線程爬取平均耗時對比Fig.2 Comparison of average time consumption of single thread crawling

表2 單線程爬取耗時對比Tab.2 Single thread crawling time comparison(單位:秒/次)
5.2.3 多線程運行下爬蟲性能分析
采用多線程爬取網頁實驗中,統一開發并發線程數為16個,分別運行三種爬蟲程序爬取目標網站網頁數量1,000 頁且運行3 次,計算耗時平均值。表3顯示為單線程和多線程爬取的比較情況。分析發現以下情況:(1)Requests、Selenium和Scrapy爬蟲在多線程爬取時,平均耗時分別為25.39 s、172.12 s和23.52 s,平均每頁耗時分別為0.03 s、0.17 s和0.02 s,Scrapy和Requests爬蟲耗時最少并且耗時差距接近,而Selenium爬蟲耗時依然最多。(2)Requests和Selenium爬蟲采用多線程爬取頁面時,耗時明顯少于單線程,而Scrapy爬蟲耗時幾乎不變,如圖3所示。

圖3 單線程和多線程爬取平均耗時對比圖Fig.3 Comparison chart of average time consumption of single thread and multi-thread crawling

表3 平均耗時對比Tab.3 Average time consumption comparison(單位:秒/1,000 頁)
5.2.4 反爬蟲規則下爬蟲登錄對比分析
目前,很多網站具有一定的反爬蟲機制,但對網絡爬蟲的相關研究,除robots這一“君子協定”外,并無相關的法律法規限制[8]。研究發現“中國裁判文書網”設置的反爬蟲機制嚴謹,故以此作為實驗對象對比不同爬蟲技術的繞過效果。
在手動測試中,打開網頁輸入用戶名、密碼并多次登錄網站后,會跳出登錄驗證網頁,必須正確輸入驗證碼才允許操作人員登錄。在Selenium技術開發的網絡爬蟲測試中,采用“程序睡眠+鍵盤輸入+自動填寫”進行繞過登錄。首先啟動爬蟲程序調用本地瀏覽器直接訪問驗證網頁,使用time.sleep()方法讓爬蟲進程睡眠20 s,以提供鍵盤輸入信息的操作時間;其次直接手動在瀏覽器輸入驗證碼證實非機器人行為,等睡眠結束后程序再調用click()方法自動執行確認按鈕,實現驗證并跳轉到登錄頁面;再次使用find_element()和send_keys()方法定位文本框并自動填入用戶名和密碼;最后調用click()方法點擊登錄按鈕,完成爬蟲模擬登錄。爬蟲登錄網站獲取到用戶的Cookies后,可以應用Cookies信息在其他爬蟲技術,實現網頁數據定制化爬取。
在模擬登錄過程中,Selenium會打開一個瀏覽器,操作頁面全程實時可視化,顯現爬蟲對網頁的操作及元素變化,包括文本填寫、頁面跳轉、新建網頁等。由于網頁中存在隨機驗證碼進行非機器人操作驗證,如果使用Requests、Scrapy技術開發的網絡爬蟲,則無法通過自動填報驗證碼信息突破網站的反爬蟲機制。
本文研究了基于Python的Requests、Scrapy和Selenium爬蟲技術,開發實現了單線程、多線程等6 個網絡爬蟲程序,驗證了不同爬蟲技術之間的性能和技術實現差異。從實驗數據來看,在排除其他因素干擾的情況下,只考慮爬取速度,則Requests技術、Scrapy技術單線程爬取網頁數據速度相當,并且遠快于Selenium技術。若使用多線程爬取,Scrapy技術的爬取速度遠快于Requests技術,Selenium技術的爬取速度依舊最慢且性能表現很不理想。在考慮爬取速度的基礎上,結合3 個爬蟲技術的特征,可得出Requests技術爬取速度中規中矩,在Python內置模塊的基礎上高度封裝了HTTP庫,入門簡單,對面向深度定制或小批量數據的爬蟲開發更為合適;Scrapy使用了異步網絡框架代碼,既簡化了代碼邏輯,又提高了開發效率,線程并發性能顯而易見,但代碼的自定義開發要契合Scrapy框架,遇到目標數據涉及多個關聯URL,則開發不夠靈活,入門稍難,偏向適用于開發網站級別的網絡爬蟲,不適合深度定制;Selenium技術開發的網絡爬蟲,本質上是驅動瀏覽器對目標站點發送請求,瀏覽器在訪問目標站點后,需要把HTML、CSS、JS等靜態資源加載完畢,因而整體效率在3 個技術中最低,但其會解析執行目標網頁的CSS、JS代碼,可以避開一系列復雜的通信流程,具有繞過復雜的反爬蟲機制能力,這方面的能力優于Requests和Scrapy已被證實。網絡爬蟲的實際開發遇到的網站場景較為復雜、多樣,要根據不同業務需求選擇不同的爬蟲技術,一項系統的業務往往要多種爬蟲技術配合使用才能達到獲取數據的目的。