給自己的爬蟲做一個(gè)簡單的動(dòng)態(tài)代理池

使用代理服務(wù)器一直是爬蟲防BAN最有效的手段,但網(wǎng)上的免費(fèi)代理往往質(zhì)量很低,大部分代理完全不能使用,剩下能用的代理很多也只有幾分鐘的壽命,沒法直接用到爬蟲項(xiàng)目中。
下面簡單記錄一下我用scrapy+redis實(shí)現(xiàn)動(dòng)態(tài)代理池的過程。

我對(duì)“動(dòng)態(tài)代理池” 的需求

我的爬蟲項(xiàng)目需要7*24小時(shí)監(jiān)控若干個(gè)頁面,考慮了一下希望代理池能滿足下面幾個(gè)要求:

  • 始終保持一個(gè)相對(duì)穩(wěn)定的代理數(shù)量
  • 始終保持池內(nèi)代理的高可靠率(希望90%的代理都能用)
  • 盡可能減少對(duì)爬蟲項(xiàng)目代碼的更改

參考過的項(xiàng)目

找過一些現(xiàn)成的輪子,但發(fā)現(xiàn)或多或少都不太符合我的需求

kohn/HttpProxyMiddleware
一個(gè)“被動(dòng)”選擇代理的方式。在scrapy middleware中加入大量代碼,讓爬蟲在代理失效后再去代理網(wǎng)站找代理,會(huì)有下面幾個(gè)問題:

  • 大多數(shù)情況下始終使用一個(gè)代理去訪問,造成流量集中在一個(gè)IP上,可能導(dǎo)致代理IP被BAN。
  • 切換代理的過程比較耗時(shí),導(dǎo)致爬蟲性能下降比較厲害
  • 所有邏輯都嵌套在了爬蟲項(xiàng)目里面,有兼容性和可移植性方面的問題(有多個(gè)爬蟲的話每個(gè)都要改一遍..)
  • 基于python2寫的,我的項(xiàng)目在python3上..

jhao104/proxy_pool
這個(gè)幾乎和我想要的一樣,但還是因?yàn)橄旅鎺c(diǎn)原因沒有使用:

  • 基于SSDB,這邊沒有現(xiàn)成的SSDB,因?yàn)橐呀?jīng)在用Redis了不想專門去裝一個(gè)
  • 只管定時(shí)收集代理,在收集過程中做一次驗(yàn)證。但事實(shí)上收集到的代理即便通過了驗(yàn)證,也可能活不過10分鐘,時(shí)間一長代理池內(nèi)就會(huì)有很多過期的代理,需要在爬蟲代碼中處理這些過期代理(爬蟲代碼調(diào)用delete刪除)。

設(shè)計(jì)思路和代碼

看了那么多方案,我就在想:能不能讓代理池具有自我檢查自我修復(fù)的功能?這樣我們的爬蟲就只需隨機(jī)拿一個(gè)代理用就可以了,就算恰巧拿到一個(gè)失效代理,只要做一次retry,代理池的修復(fù)機(jī)制可以保證retry的時(shí)候失效的代理已經(jīng)被移走了,不會(huì)再次取到。

簡單規(guī)劃一下:

  • 我們需要一個(gè)自檢程序,它每10S跑一次,保證代理池內(nèi)所有代理至少在10S內(nèi)有效
  • 我們需要一個(gè)代理獲取的程序,當(dāng)代理池內(nèi)代理數(shù)量過低時(shí)(閾值定為<5),訪問免費(fèi)代理網(wǎng)站補(bǔ)充新代理
  • 我們需要一個(gè)調(diào)度程序,用來監(jiān)控代理池?cái)?shù)量并調(diào)用上面兩個(gè)程序,維持代理池平衡。
  • 作為私有代理池就維護(hù)在redis了(SET),讓爬蟲直接從redis里取代理。

對(duì)應(yīng)的代碼就有這么三個(gè)部分:

  • 一個(gè)scrapy爬蟲去爬代理網(wǎng)站,獲取免費(fèi)代理,驗(yàn)證后入庫 (proxy_fetch)
  • 一個(gè)scrapy爬蟲把代理池內(nèi)的代理全部驗(yàn)證一遍,若驗(yàn)證失敗就從代理池內(nèi)刪除 (proxy_check)
  • 一個(gè)調(diào)度程序用于管理上面兩個(gè)爬蟲 (start.py)

強(qiáng)行畫個(gè)流程圖:

hq-proxies.png

爬蟲部分全部用scrapy寫了,其實(shí)沒必要,用requests就夠了..但做的時(shí)候剛學(xué)scrapy,就順便練練手了..
start.py的調(diào)度方式比較粗暴,直接起兩個(gè)線程,在線程內(nèi)用os.system調(diào)用scrapy爬蟲(畢竟輕量級(jí)代理池嘛..好吧其實(shí)就是我懶圖個(gè)方便..)

另外還有幾個(gè)調(diào)度策略需要說一下:

  • 每次調(diào)用proxy_fetch后會(huì)自動(dòng)設(shè)定一個(gè)“保護(hù)時(shí)間”10分鐘,在保護(hù)期內(nèi)除非代理池只剩一個(gè)代理了,否則不會(huì)觸發(fā)proxy_fetch,避免頻繁調(diào)用。
  • 加入了一個(gè)“刷新時(shí)間”24小時(shí),保證每24小時(shí)內(nèi)至少執(zhí)行proxy_fetch一次
  • 驗(yàn)證程序設(shè)定timeout為5秒,5秒內(nèi)沒訪問到測(cè)試頁面就認(rèn)為驗(yàn)證失敗

其他細(xì)節(jié)可以看源碼:arthurmmm/hq-proxies

部署和使用

需要先改一下配置文件hq-proxies.yml,把Redis的地址密碼之類的填上,改完后放到/etc/hq-proxies.yml下。
在配置文件中也可以調(diào)整相應(yīng)的閾值和免費(fèi)代理源和測(cè)試頁面。
測(cè)試頁面需要頻繁訪問,為了節(jié)省流量我在某云存儲(chǔ)上丟了個(gè)helloworld的文本當(dāng)測(cè)試頁面了,云存儲(chǔ)有流量限制建議大家換掉。。驗(yàn)證方式很粗暴,比較一下網(wǎng)頁開頭字符串。。

另外寫了個(gè)Dockerfile可以直接部署到Docker上(python3用的是Daocloud的鏡像),跑容器的時(shí)候記得把hq-proxies.yml映射到容器/etc/hq-proxies.yml下。
手工部署的話跑pip install -r requirements.txt安裝依賴包

在scrapy中使用代理池的只需要添加一個(gè)middleware,每次爬取時(shí)從redis SET里用srandmember隨機(jī)獲取一個(gè)代理使用,代理失效和一般的請(qǐng)求超時(shí)一樣retry,代理池的自檢特性保證了我們r(jià)etry時(shí)候再次拿到失效代理的概率很低。middleware代碼示例:

class DynamicProxyMiddleware(object):
    def process_request(self, request, spider):
        redis_db = StrictRedis(
            host=LOCAL_CONFIG['REDIS_HOST'], 
            port=LOCAL_CONFIG['REDIS_PORT'], 
            password=LOCAL_CONFIG['REDIS_PASSWORD'],
            db=LOCAL_CONFIG['REDIS_DB']
        ) 
        proxy = redis_db.sismember(PROXY_SET, proxy):
        logger.debug('使用代理[%s]訪問[%s]' % (proxy, request.url))
        request.meta['proxy'] = proxy

在其他爬蟲框架下使用也是類似的。

最后放一張萌萌噠日志菌觸發(fā)proxy_fetch時(shí)候的截圖:

Paste_Image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1 前言 作為一名合格的數(shù)據(jù)分析師,其完整的技術(shù)知識(shí)體系必須貫穿數(shù)據(jù)獲取、數(shù)據(jù)存儲(chǔ)、數(shù)據(jù)提取、數(shù)據(jù)分析、數(shù)據(jù)挖掘、...
    whenif閱讀 18,313評(píng)論 45 523
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,569評(píng)論 19 139
  • 風(fēng)險(xiǎn)分為不同的層次面,我們現(xiàn)階段可分為規(guī)避,降低,自留。 工作中不可避免的人員去留,相對(duì)表現(xiàn)通過觀察與溝通提前做好...
    楊平的閱讀 316評(píng)論 0 0
  • 企業(yè)所有的制度出臺(tái)一定有它獨(dú)特的緣由,企業(yè)各項(xiàng)規(guī)章制度是企業(yè)的內(nèi)部法規(guī), 是企業(yè)日常管理行為的重要依據(jù),它可...
    YY的世界閱讀 613評(píng)論 2 1
  • 今天參加了一個(gè)世界詩歌日的朗誦活動(dòng)。詩歌配春雨,不錯(cuò)。 分享一下我的自選詩歌。 推薦一個(gè)APP,為你讀詩。
    寒晗Tylor閱讀 250評(píng)論 0 3

友情鏈接更多精彩內(nèi)容