scrapy: 使用HTTP代理繞過網站反爬蟲機制
scrapy提供下載中介軟體機制, 可以在請求佇列與下載請求之間做一些動作. scrapy本身也提供了一個ProxyMiddleware, 但是它只能使用固定的IP地址, 由於免費的代理相當不穩定, 很多代理其實根本不能用. 因此需要對ProxyMiddleware改造使得這個middleware能夠發現代理不可用, 並且在發現不可用的時候切換到另一個代理.
scrapy提供的ProxyMiddleware相當簡單, 對其改造基本上等同於重新寫一個了…首先就是如何發現一個代理不可用. 最常見的不可用代理的症狀就是超時或者拒絕服務, 完全連不上, 為了處理這個問題, 新的ProxyMiddleware就要在process_exception裡捕捉超時和ConnectionRefused異常. 還有些代理的問題是直接返回403或者407. 於是還要在process_response中檢查response的status.
發現異常之後要換新的代理, 所以在新的ProxyMiddleware中需要一個list來儲存所有代理, 每個代理還要有些屬性, 例如valid, 這樣當發現一個代理根本連不上時將valid屬性設為False, 下次需要換代理時就忽略這些valid為False的代理, 避免再經歷一遍超時.
另外就是發現IP被ban了之後更換代理, 一開始我是直接在middleware裡處理這種情況, 但是IP被ban的檢查各個網站都不一樣, 寫死在middleware裡不太好. 於是我在spider裡檢查是否被ban, 如果被ban了則重新yield一個請求, 並設定meta["change_proxy"]=True
還有個問題就是代理數量不足的問題. 由於免費代理一般都是臨時性的, 隨著執行時間的增長, 有些代理會失效, 這樣到最後就沒有可用的代理了. 於是我在新的ProxyMiddleware裡, 每次換新代理時檢查代理列表中有效代理的數量, 如果小於一個閾值, 則從網上抓新的免費代理擴充代理列表.