昨日使用haipproxy作為代理源,對知乎
進行了資料抓取相關的效能測試,測試效果還不錯,有興趣的可以點選專案主頁檢視測試結果。但是它仍有繼續優化的空間,所以筆者打算單獨寫一篇文章來單獨闡述它現有的IP篩選策略,也就是題目說的高可用
策略。而關於部署的高可用後續文章會談及到,這裡暫時按下不表。
下文主要會談到校驗器和客戶端的IP篩選策略。
校驗器
我們知道,一個代理IP有多個屬性,比如成功請求率、響應速度、是否支援Get/Post方法、是否匿名和該IP所處位置等。這些往往也是衡量一個IP質量的可參照標準。而從網際網路上採集的免費IP大多數是短效的,所以代理IP對應的最近驗證時間也是一個很重要的參考標準。haipproxy目前主要參照請求成功率
、響應速度
、最近驗證時間
和是否匿名
這四個維度對代理IP進行篩選。精力所限,目前還未打算對IP位置進行完善,而IP位置對於已登入的賬戶來說具有比較重要的意義。還有一點是,對於同一個代理IP,代理不同網站的效果可能大不相同,所幸的是,haipproxy
可以根據自己需求定製校驗器
根據haipproxy架構篇的介紹,我們可以知道haipproxy initvalidator
會過濾掉部分透明的代理ip,另外一個過濾透明IP的地方是proxy spiders,它在抓取代理IP的時候會直接丟棄透明代理IP。因此,是否匿名
這個標註我們已經實現了,後續所有的validated queues
中儲存的都是匿名及高匿IP。
請求成功率
是以打分的方式來做的,這樣做的原因是不需要對歷時成功請求次數和失敗請求次數進行記錄和計算,優化了部分效能,又可以體現一個IP的穩定性。
那麼打分的標準又是怎樣的呢?haipproxy
會先給定一個初始分數(5)。當成功一次,我們就對該代理加1分,為了防止分數短時間急劇增大,在分數大於一定閾值(10)後就對其進行更平滑的加分處理,具體為round(10/score, 2)
,這樣,分數會越來越難升高,但是足夠衡量每個代理IP的穩定性了。當失敗一次,就要分情況處理了。我們知道,很多免費代理IP可能短時間失效,比如代理埠被關了。這種情況下,haipproxy
會直接丟棄該代理IP,因為它沒有繼續校驗的必要性了,再對它進行校驗只會增加校驗器的負擔。但是如果本次校驗超時了,校驗器會將該代理IP減一分,直到分數為0,則刪除。對於不同分數的IP的選取會在客戶端部分進行說明。
響應速度
這個標準比較容易評判,haipproxy
的做法是為校驗器爬蟲載入一個profilemiddleware,從而獲取到請求成功的代理IP的響應時間。同理,最近校驗時間也比較容易獲取到,我們使用redis的zset
資料結構來儲存它。
客戶端
目前,haipproxy
實現了兩種形式的客戶端:squid和py_cli。前者是語言無關的,它使用squid作為二級代理,它會定時自動更新squid配置檔案,以獲取新的可用代理,獲取的方法和使用py_cli
相同,下面會講到。使用squid作為二級代理的好處是便於服務化,同時是語言無關的,我們的爬蟲端只需要將代理設定為http://squid_host:3128
就可以了,不用關心其它,但是這麼做有一點不好的是,它的排程是輪詢IP,並且對於不可用或者低質量IP的處理和反饋是不透明的。基於這點,有必要實現基於不同語言的客戶端。
py_cli是haipproxy
代理獲取的python實現。挑選可用代理的具體做法如下:
-
根據配置檔案的設定分別從
validated_queue
、ttl_queue
和speed_queue
中挑選出滿足配置引數需求的代理再對其求交集,引數預設值是LOWEST_SCORE = 6
、TTL_VALIDATED_RESOURCE = 2
和LONGEST_RESPONSE_TIME = 10
,表示的意思是選擇分數大於6且最近驗證時間在2分鐘以內且最長響應時間不超過10s的代理。這樣可以對上述的各個標準做合理的保證。在上述挑選方式選出來的代理數量不足(len(proxies) < len(pool)*2
)的時候,會放寬挑選要求,對速度和最近驗證時間求交集,然後和成功率做並集。如果代理數量還不足,它還會放低要求,對滿足最近驗證時間和成功率的集合做並集。 -
在爬蟲客戶端呼叫
py_cli
的時候,代理客戶端ProxyFetcher
會首先呼叫refresh()
方法,如果ProxyFetcher
中的可用代理量不夠,那麼就會通過上一步的演算法對IP池進行擴充,如果數量足夠,那麼就會根據代理的排程策略選取合適的IP進行使用。 -
目前共有兩種代理排程策略。(1)輪詢策略。代理池是一個佇列結構,每次從隊首拿一個IP進行使用,如果該IP請求成功,則放到隊尾,如果不成功,則需要呼叫
ProxyFetcher
的proxy_feedback()
方法將結果進行反饋。這種策略的好處是IP負載比較均衡。但是缺點在於,IP質量參差不齊,有的響應時間很快,有的響應時間很慢,並且高質量的免費代理IP的生命週期可能很短,這樣就無法充分利用。(2)貪婪策略。使用此種策略的時候,需要爬蟲端對每次請求的響應時間進行記錄,每次使用後呼叫proxy_feedback()
方法以決定該代理IP是否繼續下一次請求的時候被使用。如果使用某個代理IP的響應時間低於傳入的response_time
引數,那麼就會一直使用它,直到不能用就從代理池中刪除。如果時間高於了response_time
,那麼它會把該IP放入隊尾。概括起來,該策略就是低質量IP輪詢,高質量IP一直使用。
上述便是目前關於haipproxy的代理IP挑選策略的所有細節。如果專案對您有用,不妨在Github上給個star。