Scrapy入門到放棄01:開啟爬蟲2.0時代
- 2021 年 4 月 21 日
- 筆記
- Scrapy, Scrapy入門到放棄, 爬蟲
前言
Scrapy is coming!!
在寫了七篇爬蟲基礎文章之後,終於寫到心心念念的Scrapy了。Scrapy開啟了爬蟲2.0的時代,讓爬蟲以一種嶄新的形式呈現在開發者面前。
在18年實習的時候開始接觸Scrapy,花了一個月的時間,理論結合實踐學習了Scrapy。本篇文章不寫代碼操作,只講前因後果及理論,願你懂得Scrapy。
原生爬蟲面臨問題
無論使用Java的Jsoup也好,python的requests也罷,開發爬蟲都會面臨下面幾個問題:
1.分佈式
爬蟲程序一般只運行在一台主機上,如果是一模一樣的爬蟲程序部署在不同的主機上,那都是獨立爬蟲程序。如果想要弄一個分佈式的爬蟲,通常的思路是將爬蟲程序分為url採集和數據採集兩個部分。
現將url爬取下來放入到數據庫中,然後通過where條件限制,或者直接使用redis的list結構,讓不同主機上的爬蟲程序讀取到不同的url,然後進行數據爬取。
2.url去重
爬取數據的時候會經常遇到重複的url,如果重複爬取是不是浪費時間。通過url去重的思路就是:將爬取的url放入到集合中,每次爬取都去判斷url是否存在於集合中。那麼,如果程序中途停止了,這個內存中集合也將不復存在,再次啟動程序,將無法判斷哪些是已經爬取過的。
那麼就用數據庫,將已經爬取過的url插入到數據庫中,這樣就算重啟程序,爬取過的url也不會丟失了。可是如果我就是想重新開始爬取,是不是還得手動清空數據庫中的url表。每次查詢數據庫耗費的時間,這都是需要考慮的。
3.斷點續爬
假如有1000個頁面需要爬取,爬到第999個頁面,進度條馬上滿格的時候,程序咯噔一下掛了,就差一個,但是還是沒爬完啊,咋整?我選擇重新啟動程序,那麼你說我怎麼樣才能直接從第999個開始爬取呢?
這裡先講講我寫的第一個爬蟲:爬取10+個地市的poi信息。
實習,第一次開發爬蟲,也不知道有高德poi接口啥的,於是就找了個網站來爬取poi信息。當時那個網站估計還在起步階段,服務器帶寬應該不高,訪問速度是真的慢,而且動不動維護停站,所以我的程序也得跟着停止。如果每次啟動都重新爬取,估計幾年也爬不完,於是我想了個辦法。
我先將所有地市下所有區縣數據的條數(網站上有)先手動錄入到數據庫表中,每次重新啟動爬蟲程序的時候,先統計結果數據表中各個區縣已經爬取的條數,與總條數進行對比。如果小於的話,說明還沒有爬取完,然後通過某區縣已爬取條數 / 網站每頁展示條數計算出我已經爬取到此區縣的頁數,再通過餘數定位到我爬到了此頁面的第幾個。通過這種方法,最後無丟失爬取了163w條數據。
換種思路,將爬取的url放到表中,重啟程序開始爬取url的時候,先去判斷url是否存在於數據表中,如果存在就不進行爬取,這樣也能實現斷點續爬。也是沿用了原始的url的去重的思路。
4.動態加載
在第六篇基金篇寫了一個jsonp的動態加載,算是比較簡單的一種,只要找到請求接口獲取數據進行處理即可。第七篇寫了電視貓的eval()的js加密,這算是很複雜的一種動態加載。請求接口的參數是加密的,需要耗費大量時間來分析密密麻麻的js,來計算出這個186位的參數。
so,有沒有一種方式讓我既能脫離閱讀分析js,還能繞過動態加載?
sure!!首先關於動態加載,可以理解為瀏覽器內核通過執行js在前端渲染數據。那麼我們在程序中搞個瀏覽器內核,我們直接獲取js渲染後的頁面數據不就可以了么?
通常使用selenium + chrome、phantomjs、pyvirtualdisplay來處理動態加載,但是或多或少都會有性能問題。
上面說了那麼多,根據一貫的套路,大家也應該知道接下來我要說什麼了。
關於Scrapy
Scrapy帶給我的感受就是:模塊分明、結構封裝、功能強大。
WHAT
Scrapy是一個分佈式爬蟲框架,我把它比作成爬蟲界的Spring。reqeusts就像是servlet一樣,各種功能邏輯都需要自己去實現,而Spring做了集成,底層對用戶透明。
就像我們知道,Spring是在application配置文件中初始化bean,在mapper中定義數據庫操作一樣,而使用者無需關心Spring是如何讀取這些配置文件進行各種操作的。同樣,Scrapy也提供了這樣的功能配置。
所以說,Scrapy是一個爬蟲框架,requests是一個爬蟲模塊,兩者是有區別的。
WHY
我的政治老師曾經說過:沒有無緣無故的愛,也沒有無緣無故的恨。 根據我個人的使用體驗,說一下我為什麼那麼推薦Scrapy。
- 性能:基於Twisted進行異步請求,怎一個快字了得!
- 配置化:通過配置文件對請求並發、延遲、重試次數等進行定義
- 插件豐富:提供了動態加載、斷點續爬、分佈式的解決方案,幾行配置即開即用
- 命令行操作:通過命令行可以生成、啟停、監控爬蟲狀態等
- Web界面操作:集成了Web界面來啟停、監控爬蟲
- 提供測試環境:提供了shell交互測試環境
HOW
Scrapy又是框架、功能還那麼強大,是不是很難學會啊。
這種擔憂大可不必,Scrapy的安裝和普通python模塊的安裝一樣,只要了解其中四個模塊的作用,入門極其簡單。而Scrapy爬蟲程序的開發邏輯,代碼更少、層次更分明,比requests要簡單很多。
應用場景
Scrapy作為一個框架,有人覺得scrapy太重量級了,不如requests用起來輕便。在這裡只能說,應用場景和側重點不一樣。
Scrapy的開發更像是一個工程項目開發。通常用來做多數據源的爬蟲數據整合,例如整合視頻、小說、音樂、漫畫等信息數據到一個數據表中。開發者只需事先約定好的數據字段,即可進行多人協作開發,因為scrapy通過yield關鍵字即可將數據放到數據庫,無需再去顯式地調用任何方法。
而requests更適合無需進行統一管理、無需分佈式部署的單個爬蟲程序的開發。
結語
其實,第一篇應該寫Scrapy的架構與安裝,但是我覺得用一個技術前,了解這個技術的功能和應用場景還是很有必要的,所以寫了這一篇理論知識。
這篇文章寫了兩遍,第一遍寫完了之後,不知道什麼原因,在編輯器里被覆蓋了,所以只能再重新寫一遍。辛虧中間部分截圖發給過朋友,還能少寫一部分。我也終於明白了曾經網上流傳的一種心情:作業寫完被狗撕了,不想再寫一遍。
希望本篇文章能讓你對爬蟲的理論知識有更深層次的了解,期待下一次相遇。
95後小程序員,寫的都是日常工作中的親身實踐,置身於初學者的角度從0寫到1,詳細且認真。
文章會在公眾號 [入門到放棄之路] 首發,期待你的關注。