Cookies池的搭建

平時我們在對網(wǎng)站進行數(shù)據(jù)抓取的時候,可以抓取一部分頁面或者接口,這部分可能沒有設(shè)置登錄限制徘溢。但是如果要抓取大規(guī)模數(shù)據(jù)的時候吞琐,沒有登錄進行爬取會出現(xiàn)一些弊端。

  • 對于一些設(shè)置登錄限制的頁面然爆,無法爬取
  • 對于一些沒有設(shè)置登錄的頁面或者接口顽分,一旦IP訪問頻繁,會觸發(fā)網(wǎng)站的反爬蟲

所以我們可以構(gòu)建一個Cookies池施蜜,存儲用戶名和cookie的映射卒蘸。


以下是它的功能模塊


Cookies池架構(gòu).png


1 . 存儲模塊


功能:存儲著用戶名與密碼,用戶名與cookie翻默。這里我們使用redis中的散列的數(shù)據(jù)結(jié)構(gòu)來存儲關(guān)系映射缸沃。在Python中使用redis這個庫來獲取連接。


redis庫中對散列的操作方法

  • hset(name修械,key趾牧,value) (為鍵名為name的hash表添加鍵值對)
  • hget(name,key) (返回鍵名為name的hash表中key的值)
  • hincrby(name肯污,key翘单,amount=1) (為鍵為name的hash表中key字段的值加上amount)
  • hdel(name,*keys) (刪除鍵名為name的hash表中的key的映射)
  • hlen(name) (獲取鍵名為name的hash表中鍵值對的個數(shù))
  • hkeys(name) (獲取鍵名為name的hash表中的所有鍵值對的鍵名)
  • hvals(name蹦渣,key) (獲取鍵名為name的hash表中的key的值)
  • hgetall(name) (獲取鍵名為name的所有鍵值對)



    class RedisClient(object):
          def __init__(self,type_,website):
              self.client StrictRedis(host=REDIS_HOST,port=REDIS_PORT,\
                        password=REDIS_PASS)
              self.website = website
              self.type = type_
            
          def name(self):
              return "{type}:{website}".format(type=self.type,\
                        website=self.website)      
            
          def set(self,username,value):
              return self.client.hset(self.name(),username,value)
            
          def delete(self,username):
              self.client.hdel(self.name(),username)
                
          def count(self):
              return self.client.hlen(self.name())
            
          def get(self,username):
              return self.client.hget(self.name(),username)
            
          def username(self):
              print(self.client.hkeys(self.name()))
              return self.client.hkeys(self.name())
        
          def all(self):
              return self.client.hgetall(self.name())
        
          def random(self):
              return random.choice(self.client.hvals(self.name()))



2 . 生成模塊


功能:是通過迭代取出accounts散列表(存儲用戶名和密碼)中所有的用戶名哄芜,判斷在cookies散列表中是否有對應(yīng)賬號的cookies,如果沒有柬唯,就調(diào)用模擬登錄程序去獲取cookie认臊,然后寫入redis中



    class CookieGenator(object):
        def __init__(self,website):
            self.website = website
            self.accounts = RedisClient('accounts',website)
            self.cookies = RedisClient('cookies',website)
            self.init_browser()
        
        def init_browser(self):
            # 根據(jù)瀏覽器類型初始化一個瀏覽器并返回
            
        def __del__(self):
            self.close()
    
        def close(self):
            # 執(zhí)行關(guān)閉瀏覽器操作
        
        def process_item(self,cookies):
            # 遍歷所有的cookie,取出每一個cookie的name和value字段锄奢,
            # 組成一個json并返回
    
        def run(self,accounts,cookies):
            # 判斷每一個賬號是否生成對應(yīng)的cookie
        
        def new_cookies(self,username,password):
            # 不同的站點獲取的cookie的方式不同失晴,所以不同的站點可以擴展該類
            # 的子類,然后重寫這個方法拘央,實現(xiàn)各自獲取cookies的方法
            



3 . 檢測模塊


功能:通過迭代拿出所有賬號的Cookies涂屁,然后使用requets測試一下是否可用,如果返回的狀態(tài)碼不是200灰伟,那說明無效拆又,把對應(yīng)的用戶名與cookie的映射刪除。



    class VerifyCookie(object):
    
        def __init__(self,website="default"):
            self.website = website
            self.accounts = RedisClient("accounts",self.website)
            self.cookies = RedisClient("cookies",self.website)
    
        def test(self,username,cookie):
            # 測試對應(yīng)站點袱箱,返回200說明cookie有效
            # 不同站點可以以此為父類進行擴展遏乔,重寫該方法,實現(xiàn)自己的測試邏輯
            
        def run(self):
           # 迭代拿出所有的cookies发笔,然后循環(huán)調(diào)用`test`方法測試是否可用
           # 如果cookie失效,就在redis刪除對應(yīng)的鍵值對
    



4 . 接口模塊


功能:為爬蟲提供接口凉翻,用于獲取隨機cookie(Cookie池最終也是要被爬蟲使用的了讨,所以需要提供一個網(wǎng)頁接口用于獲取Cookies)



    from flask import g,Flask
    
    __all__ = ['app']
    app=Flask(__name__)
    
    def get_conn():
        # 在g對象中設(shè)置屬性
        # key:散列表的鍵名與value:RedisClient對象的映射
        # eg   accounts:weibo ----  RedisClient("accounts","weibo")
    
    @app.route("/")
    def index():
        # 首頁內(nèi)容
        return "<h2>Welcome to Cookies Pool System</h2>"
    
    @app.route("/<website>/count")
    def count(website):
        # 獲取cookies的數(shù)量
        
    
    @app.route("/<website>/add/<username>/<password>")
    def add_attr(website,username,password):
        # 通過在url中填入相應(yīng)信息為散列表中添加對應(yīng)站點的用戶名和密碼
    
    @app.route("/<website>/random")
    def random(website):
        # 獲取隨機cookie
    
    def run():
        app.run()
    


5 . 調(diào)度模塊


功能:開啟三個進程,打開接口,生成Cookie前计,檢測Cookie 胞谭,定時檢測Cookie的可用性,生成Cookies男杈,刪除hash表中無用Cookies丈屹。



    class Scheduler(object):
    
        @staticmethod
        def api():
            print("API接口開始運行")
            app.run(host=API_ADDRESS,port=API_PORT)
            
        
        @staticmethod
        def generate_cookies(cycle=CYCLE):
            print("開始生成cookies")
            while True:
                try:
                    # 通過eval生成對應(yīng)的生成器對象,然后生成Cookies
                except Exception as e:
                    raise e    
    
        @staticmethod
        def verify_cookies(cycle=CYCLE):
            print("開始檢查cookies")
            while True:
                # 通過eval動態(tài)生成對應(yīng)的測試類對象伶棒,然后執(zhí)行測試
        
    
        def run(self):
            # 開啟三個進程旺垒,調(diào)用上面三個方法
    


note: 附上代碼地址Cookies池


小結(jié):Cookies池對與爬取大規(guī)模數(shù)據(jù)很有用(有些頁面設(shè)置了登錄限制),單賬號爬取太快可能會被封IP肤无,可以通過切換賬號來解決這個問題先蒋,另外要提升爬取效率的話可以配合使用代理來避免被反爬。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末宛渐,一起剝皮案震驚了整個濱河市竞漾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌窥翩,老刑警劉巖业岁,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異寇蚊,居然都是意外死亡叨襟,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門幔荒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來糊闽,“玉大人,你說我怎么就攤上這事爹梁∮矣蹋” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵姚垃,是天一觀的道長念链。 經(jīng)常有香客問我,道長积糯,這世上最難降的妖魔是什么掂墓? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮看成,結(jié)果婚禮上君编,老公的妹妹穿的比我還像新娘。我一直安慰自己川慌,他們只是感情好吃嘿,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布祠乃。 她就那樣靜靜地躺著,像睡著了一般兑燥。 火紅的嫁衣襯著肌膚如雪亮瓷。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天降瞳,我揣著相機與錄音嘱支,去河邊找鬼。 笑死挣饥,一個胖子當著我的面吹牛除师,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播亮靴,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼馍盟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了茧吊?” 一聲冷哼從身側(cè)響起贞岭,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎搓侄,沒想到半個月后瞄桨,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡讶踪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年芯侥,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片乳讥。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡柱查,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出云石,到底是詐尸還是另有隱情唉工,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布汹忠,位于F島的核電站淋硝,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏宽菜。R本人自食惡果不足惜谣膳,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望铅乡。 院中可真熱鬧继谚,春花似錦、人聲如沸隆判。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽侨嘀。三九已至臭挽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間咬腕,已是汗流浹背欢峰。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留涨共,地道東北人纽帖。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像举反,于是被迫代替她去往敵國和親懊直。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)載火鼻,覺得這篇寫 SQLAlchemy Core室囊,寫得非常不錯。不過后續(xù)他沒寫SQLAlchemy ORM... ...
    非夢nj閱讀 5,414評論 1 14
  • 會話(Session)跟蹤是Web程序中常用的技術(shù)魁索,用來跟蹤用戶的整個會話融撞。常用的會話跟蹤技術(shù)是Cookie與Se...
    chinariver閱讀 5,620評論 1 49
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)粗蔚,斷路器尝偎,智...
    卡卡羅2017閱讀 134,659評論 18 139
  • 濕衣小姐姐
    babybud閱讀 278評論 0 2
  • 因為一些特殊情況,最近在家里休息鹏控,可是科室的一些事情致扯,我都沒有落下,就像最近又有哪個病人病情危重啦当辐,哪個主任又是半...
    李蘇珊閱讀 339評論 0 0