歷時大致兩個月,到現在終於完成了高可用分散式代理IP池,目前開源在了Github上。寫這個專案的原因主要有兩點,一是自己平時的部分工作需要和爬蟲打交道,代理IP在有的時候可以發揮非常重要的作用,調研過一些開源的代理IP採集程式,發現在抓取、解析、校驗、資源排程等這些方面總有一些不盡人意的地方;二是和一個網友(不嚴格的說算得上是伯樂)的交流讓我有了關於使用Scrapy來寫分散式爬蟲的一些想法,正好可以藉助這個機會來嘗試證實這些想法。
這篇文章的目的是闡述haipproxy的主要架構和流程。該專案關鍵部分是
- 基於Scrapy和Redis的分散式爬蟲,用作IP抓取和校驗,對應於專案的crawler
- 基於Redis實現的分散式任務排程工具,對應於專案的scheduler和redis_util.py
Crawler分為代理抓取和校驗,兩者實現思想類似,主要使用Scrapy的spider_idle
訊號和DontCloseSpider
異常來阻止Scrapy在沒有資料的時候關閉,靈感來自scrapy-redis。為了方便闡述,我畫了一張包含各個元件的流程圖,如下
- 啟動排程器,包括代理爬蟲排程器和校驗爬蟲排程器。排程器會讀取rules.py中待抓取的網站,將其編排成任務存入各個任務佇列中
- 啟動各個爬蟲,包括IP抓取和校驗程式。專案中爬蟲和排程器都是高可用的,可以根據實際情況進行分散式部署,無需改動程式碼。由於本文的目標不是寫成該專案的詳細使用文件,所以省略瞭如指定啟動爬蟲型別和排程器型別的介紹
- 代理IP採集爬蟲啟動後會到對應的任務佇列中獲取任務並執行,再把獲取到的結果存入一個
init
佇列中 init
佇列由一個特殊的校驗器HttpbinInitValidator
進行消費,它會過濾掉透明代理,再把可用代理輸入各個Validated
佇列中- 排程器會定時從
Validated
佇列中獲取代理IP,再將其存入一個臨時的佇列。這裡用一個臨時佇列是為了讓校驗更加公平,如果直接從Validated
佇列中獲取資源進行校驗,那麼會增大不公平性 - 這時候各個校驗器(非
init
校驗器)會從對應的臨時佇列中獲取待校驗的IP並對其進行校驗,此處省略校驗細節 - 校驗完成後再將其放回到
Validated
佇列中,等待下一輪校驗 - 請求成功率(體現為分數)、響應速度和最近校驗時間滿足settings.py所配置要求的代理IP將會被爬蟲客戶端所消費
- 為了遮蔽各個呼叫語言的差異性,目前實現的客戶端是
squid
客戶端,它可以作為爬蟲客戶端的中介軟體
到此,整個流程便完了。
效果測試
以單機模式部署haipproxy
和測試程式碼,以知乎為目標請求站點,
每一萬條成功請求為統計結果,實測抓取效果如下
請求量 | 時間 | 耗時 | IP負載策略 | 客戶端 |
---|---|---|---|---|
0 | 2018/03/03 22:03 | 0 | greedy | py_cli |
10000 | 2018/03/03 11:03 | 1 hour | greedy | py_cli |
20000 | 2018/03/04 00:08 | 2 hours | greedy | py_cli |
30000 | 2018/03/04 01:02 | 3 hours | greedy | py_cli |
40000 | 2018/03/04 02:15 | 4 hours | greedy | py_cli |
50000 | 2018/03/04 03:03 | 5 hours | greedy | py_cli |
60000 | 2018/03/04 05:18 | 7 hours | greedy | py_cli |
70000 | 2018/03/04 07:11 | 9 hours | greedy | py_cli |
80000 | 2018/03/04 08:43 | 11 hours | greedy | py_cli |
可見haipporxy
的代理效果還算不錯,在開始的時候可以達到1w/hour
的請求量,幾個小時候請求量請求量
降為了5k/hour
。降低的結果可能有三個: (1)隨著資料量的增大,Redis的效能受到了一定的影響(2)知乎校驗器在把Init Queue
中的代理消費完之後,由於是定時任務,所以導致某段時間內新鮮的IP空缺。而免費IP大多數都是短效的,所以這段時間出現了IP的空缺;(3)由於我們採用的是greedy
模式呼叫IP,它的呼叫策略是: 高質量代理IP會一直被呼叫直至該代理IP不能用或者被封,而低應速度IP會輪詢呼叫。這也可能導致高質量IP的空缺。
可見IP校驗和呼叫策略還有很大的優化空間。希望志同道合的朋友加入進來一起優化,這也挺有意思的。
專案地址: https://github.com/SpiderClub/haipproxy
歡迎star和fork,也歡迎大家交流和PR。