MongoDB 4.0 Python3.7 穩定高效的評分制IP代理池APIserver

FooProxy

穩健高效的評分制 IP代理池 + API服務提供,能夠本身插入採集器進行代理IP的爬取,支持 MongoDB 4.0 使用 Python3.7python

github 地址: FooProxy

背景

由於平時爬取某些網站數據時,常常被封IP,同時網上不少的接口又不方便,免費的也少,穩定的更少,因此本身寫了一個評分制的ip代理API進行爬蟲的供給.
起初對MySQL和MongoDB進行了兼容的編寫,後來發如今高併發的狀況下,MySQL並不能很好的讀寫數據,常常莫名其妙的出現死機、讀寫巨慢、緩執行等各類奇葩現象,對比MongoDB高效的數據文檔讀寫,最終仍是放棄了mysql的兼容。(dev分支保留了對mysql的部分支持,如爬取評分)mysql

環境

開發環境
  • PyCharm 2018.2.4 (Professional Edition)
  • Python 3.7
  • MongoDB 4.0
  • Windows 7 64bits
需安裝的庫
  • pymongo
  • aiohttp
  • flask
  • requests
  • bs4
  • lxml

項目目錄

  • APIserver

一個簡單的代理API接口服務器,使用Flask實現,能夠本身按需求寫路由邏輯。這部分固然能夠獨立出來寫,只是集成寫在了項目裏面。git

  • components

項目的主要運行部分,採集器、驗證器、打分檢測等功能實現的模塊。github

  • config

其中的DBsettings是數據庫的設置,用戶名密碼之類的,以及存儲的數據庫名,還有備用有效數據庫(standby)的自定義名字和高分穩定數據庫(stable)的自定義名字。config文件是整個項目的主要參數配置,能夠設置採集器採集間隔、驗證器的抓取驗證數量間隔和協程併發極值等。sql

  • const

項目的靜態配置,通常不用動的設置參數數據庫

  • custom

自定義模塊,能夠編寫本身要增長的爬蟲採集函數到採集器中進行數據採集django

  • log

項目日誌記錄模塊配置以及日誌flask

  • tools

一些工具函數api

  • main.py

項目入口文件服務器

基本流程

整個項目的流程其實很簡單,採集數據模塊主要是編寫代理網站的爬蟲,能夠進行任意的爬蟲增減

  • 採集數據
  • 驗證數據
  • 打分存儲
  • 循環檢測
  • 擇優剔劣
  • API調用

流程圖:
圖片描述
![實現步驟]

1.採集數據(Collector)

採集器進程是一個週期循環,使用了多線程對每個代理網站進行數據採集,即:一個代理網站爬蟲一個線程。由於沒有數據共享,這裏沒有GPL。項目內置了兩個代理數據採集爬蟲,一個是我的網站的nyloner,一個是66ip代理網站的爬蟲(在crawlers.py文件中),若是想要增長代理爬蟲,能夠本身在custom目錄下的custom.py文件中進行增長刪減,只須要保證你的爬蟲返回的結果數據結構和要求的一致就好。以下:

def some_crawler_func():
    """
    本身定義的一個採集爬蟲
    約定:
        1.無參數傳入
        2.返回格式是:['<ip>:<port>','<ip>:<port>',...]
        3.寫完把函數名加入下面的my_crawlers列表中,如
          my_crawlers = [some_crawler_func,...]
    """
    pass

my_crawlers = []

一個數據採集爬蟲函數就是一個採集器,寫完函數在my_crawlers中加進去就能夠。在config中設置一個週期時間,就可讓爬蟲按期採集更新數據。

在採集的過程當中,若是出現採集器爬蟲被封IP,能夠經過本身的APIserver請求代理,而後再繼續採集,這一部分沒有寫,不過能夠實現

2.驗證數據(Validator)

採集器進程和驗證器進程共享一個變量:proxyList,是一個MultiProcessing.Manger.List對象。能夠在多進程中
保持共享數據的同步(理論上),採集器按期採集的代理數據能夠經過proxyList實時的傳遞給驗證器進行有效性驗證,由於採集器一次傳遞的數據比較多,因此驗證器使用異步驗證,能大大提升效率,具體使用自帶的asyncio實現的.

驗證器實現基本上也是調用了一個驗證api來判斷代理的有效性,能夠本身更換api實現,可在validator.py中詳細瞭解。在config中能夠配置異步的併發量等來控制驗證器。

3.打分存儲(Rator)

打分器進程主要是與驗證器配合,當採集器採集的數據通過驗證器驗證後,肯定有效,則讓打分器進行評分,中間能夠加入自定義數據處理模塊,打分後直接存儲在standby數據庫,然後供本地檢測器進行週期檢測,打分器也是一個週期循環,不斷的對代理數據進行更新補充。內置在驗證器與掃描器中。打分器主要的三個函數:mark_success,mark_fail,mark_update.

  • mark_success 對採集器傳遞給驗證器的代理數據,驗證成功後進行一次性的評分而且存儲
  • mark_fail 對驗證器進行驗證,代理無效的數據進行失敗打分處理(達到刪除條件則刪除,不然扣分更新數據庫)
  • mark_update 對非初次打分的代理數據進行更新,即驗證有效的數據再次驗證時仍有效,則進行加分之類的數據庫更新

具體的評分步驟在下面會詳細說明,不過還有很大的提高空間,只是初步試了一下。

4.循環掃描(Scanner)

當驗證器的有效數據通過打分器存進本地standby數據庫中後,怎麼保證這一次存進去的數據之後能保證調用時仍可用呢?使用掃描器週期循環檢測!掃描器會在你給定的掃描週期間隔不斷地對本地standby數據庫進行掃描驗證,無效的數據則直接刪除,有效的數據會對其得分、響應時間、驗證時間等字段進行及時的更新,保證代理數據的實時有效。

在掃描器內部其實也是有一個驗證函數來進行掃描驗證。詳見scanner.py

5.擇優剔劣(Detector)

存儲在standby數據庫中的數據通過掃描器的掃描檢測,能夠保證其有效性,當是若是想要穩定的代理供給APIserver,那麼必須有一個檢測器來進行挑揀代理,Detector會週期性的進行掃描standby和stable兩個數據庫,對其中符合高分穩定條件的代理存進stable數據庫,對失效的高分代理進行剔除,這些均可以在config中進行自定義配置高分穩定條件。如:

#採集器採集數據時間間隔,單位:秒
COLLECT_TIME_GAP    = 3600*1
#驗證器的最大併發量
CONCURRENCY         = 100
#驗證器一次取出多少條 抓取的 代理進行驗證
VALIDATE_AMOUNT     = 500
#驗證器驗證抓取數據頻率 : 秒/次
VALIDATE_F          = 5
#驗證器請求超時重試次數
VALIDATE_RETRY      = 5
#掃描器的最大併發協程數量
COROUTINE_MAX       = 300
#掃描器一次取出多少條 本地庫 的代理進行驗證
LOCAL_AMOUNT        = 500
#掃描器驗證本地庫頻率 : 秒/次
VALIDATE_LOCAL      = 60*1
#檢測器檢測數據庫的頻率: 秒/次
DETECT_LOCAL        = 60*1
#檢測器一次取出多少條有效庫的代理進行篩選
DETECT_AMOUNT       = 1000
#檢測器一次取出多少條高分穩定數據庫的代理進行檢測
DETECT_HIGH_AMOUNT  = 1000
#高分穩定數據庫代理數據連續多少次無效則從穩定數據庫中剔除
DELETE_COMBO        = 30
#代理IP成功率的最低要求,低於此要求均刪除,100次週期測試 0.2=20%
MIN_SUCCESS_RATE    = 0.2
#有效代理數據庫數據轉至高分穩定數據庫的成功率最低要求 0.8=80%
#以及測試總數的最低要求
STABLE_MIN_RATE     = 0.8500
STABLE_MIN_COUNT    = 100

由於是對本地數據庫的io操做,使用了異步asyncio能夠大大提升效率。

6.API調用(APIserver)

有了穩定的高分代理數據,那麼就能夠掛起一個api server爲咱們的爬蟲保駕護航,這一部分能夠單獨拿出來編寫,使用其餘框架django之類的都是不錯的選擇。項目裏只是爲了演示使用,使用Flask進行了簡單的路由設置,由於測試爬蟲在本機,因此使用了下面幾個api而已,具體能夠本身擴展。

root = 'http://localhost:5000'
# 請求代理 kind爲代理種類,anony爲高匿,normal爲透明
root+'/proxy/<string:kind>'
# 請求代理 直接返回一個高匿代理
root+'/proxy'

能夠在apiserver.py中本身實現路由。

評分

簡單的評分可使代理ip篩選更加簡單,其中的具體設置能夠再const.settings中更改,一個代理IP數據的得分主要是:

  1. 一次請求的基礎分 score-basic :100-10x(響應時間-1)
  2. 請求成功的得分 score-success : (基礎分+測試總數x上一次分數)/(測試總數+1)+自定義成功加分數x成功率x連續成功數
  3. 請求失敗的得分 score-fail : (基礎分+測試總數x上一次分數)/(測試總數+1)-自定義失敗減分數x失敗率x連續失敗數
  4. 穩定性 stability : 得分x成功率x測試數/自定義精度

與三個變量成正比的穩定性根據得分設置能夠很快的兩極化穩定與不穩定的代理,從而進行篩選。

使用

  • 確保本機安裝MongoDB,而且下載好全部須要安裝庫,python3.7
  • 能夠先進行自定義的模式,在config中進行配置,能夠運行單獨的模塊進行測試,如:
#運行模式,置 1 表示運行,置 0 表示 不運行,全置 0 表示只運行 API server
  MODE = {
   'Collector' : 1,    #代理採集
   'Validator' : 1,    #驗證存儲
   'Scanner'   : 1,    #掃描本地庫
   'Detector'  : 1,    #高分檢測
 }
  • 能夠在config中的DBsettings配置好數據庫設置
  • 按照本身需求更改評份量(const.setting中,默認不用更改)
  • 配置後能夠直接在DOS下或PyCharm等有標準stdout的環境下運行 python main.py
  • 運行一段時間就能夠看到穩定的效果

不足

  • 穩定性沒有很好的標準判斷,不過100次測試85%以上的成功率就已經很好了
  • 沒有編寫驗證器與API服務器的超時請求代理功能
  • API 服務器沒有單獨拿出來編寫
  • 尚未加入存活時間的考量
  • 還沒接入爬蟲測試
  • ...

效果

  1. 備用有效數據庫,開啓1.5個小時後:

圖片描述

  1. 高分穩定數據庫

圖片描述

後話

  • 比較符合預期
  • 通過連續6天的測試,程序運行正常
  • 備用有效數據庫與高分穩定數據庫的同步更新偏差在5分鐘左右
  • 只有一個數據採集爬蟲的狀況下,一個小時採集一次,一次1000條數據[採集66ip代理網],8個小時內穩定的有效代理995左右,高分穩定的有200條左右,主要在於代理網站的質量
  • 通過併發爬蟲測試,可使用到實際項目中
相關文章
相關標籤/搜索