爬蟲:5.增量爬取和去重

增量爬取和去重

增量爬取

當(dāng)一個站點有數(shù)據(jù)更新的時候赃绊,需要進行增量爬取杆逗,通常有以下集中情況

  1. 某個特定頁面數(shù)據(jù)更新

  2. 新增了頁面

情況1的時候霜瘪,我們對此特定頁面的內(nèi)容做哈希喧半,當(dāng)然要去除動態(tài)變化的那一部分,比如有的頁面有驗證碼或者日期材义,程序定期執(zhí)行均抽,在執(zhí)行的最開始檢測此頁面的哈希值跟上次抓取是否有變化,如果有變化就開始抓取其掂。

情況2的時候油挥,我們會對頁面入口內(nèi)容做哈希,并且存儲分頁面的URL哈希值款熬,如果頁面入口哈希值發(fā)生變化深寥,獲取新增的頁面url列表,在這里需要用到url的去重贤牛,和數(shù)據(jù)去重類似惋鹅,采用redis集合類型處理。

redis集合類型不允許添加重復(fù)的數(shù)據(jù)殉簸,當(dāng)添加重復(fù)的時候時闰集,返回0沽讹,并且添加失敗。我們將所有的url list存入redis集合武鲁,當(dāng)頁面入口變化時爽雄,進行頁面url去重,只抓取新增的頁面沐鼠。

爬取結(jié)果去重

結(jié)果去重常用的有兩種方法:

  1. 布隆過濾器
  2. redis集合

布隆過濾器

其中布隆過濾器是通過寫文件的方式盲链,多個進程使用需要添加同步和互斥,較為繁瑣迟杂,不推薦多線程/進程的時候使用,另外寫文件是磁盤I/O操作本慕,耗費時間長排拷,可以累積到一定數(shù)量再一次寫入,或者利用上下文管理器在程序結(jié)束或異常退出時一次性寫入锅尘。

class Spider(object):
    def __init():
        # 布容過濾器初始化
        self.burongname = 'test.bl'
        if not os.path.isfile(self.burongname):
            self.bl = BloomFilter(capacity=100000, error_rate=0.000001)
        else:
            with open(self.burongname, 'rb') as f:
                self.bl = BloomFilter.fromfile(f)
    
    def __enter__(self):
        u"""
        上下文管理器進入入口
        """
        return self

    def __exit__(self, *args):
        u"""
        上下文管理器监氢,退出出口
        """
        if self.conn is not None:
            self.conn.close()

        with open(self.burongname, 'wb') as f:
            self.fingerprints.tofile(f)
    def get_infos(self):
        """
        抓取主函數(shù)
        """
        # 布隆過濾器使用部分, x為抓取到得數(shù)據(jù)
        x = json.dumps(i)
        if x not in self.bl:
            self.bl.add(x)

if __name__ == '__main__':
    with Spider() as MSS:
        MSS.get_infos()

上下文管理器,在主函數(shù)執(zhí)行之前執(zhí)行 def enter ,在程序運行結(jié)束或異常退出時執(zhí)行def exit藤违, 上下文管理器還可以用來統(tǒng)計程序執(zhí)行的時間浪腐。

redis集合

使用redis集合去重能夠支持多線程多進程.

利用redis集合無重復(fù)數(shù)據(jù)的特點,在redis建立集合顿乒,往其中添加數(shù)據(jù)的sha1值议街,添加成功返回1,表示無重復(fù)璧榄,添加失敗返回0特漩,表示集合中已經(jīng)有重復(fù)數(shù)據(jù)

使用: 步驟:1. 建立redis連接池 2. 重復(fù)檢查

下面的例子是接口,并提供example骨杂。

[Redis]
server=192.168.0.100
pass=123@123
# -*- coding:utf-8 -*-

"""
File Name : 'distinct'.py
Description:
Author: 'chengwei'
Date: '2016/6/2' '11:45'
python: 2.7.10
"""

import sys
import hashlib
import os
import codecs
import ConfigParser
import redis

reload(sys)
sys.setdefaultencoding('utf-8')

"""
利用redis的集合不允許添加重復(fù)元素來進行去重
"""


def example():
    pool, r = redis_init()
    temp_str = "aaaaaaaaa"
    result = check_repeate(r, temp_str, 'test:test')
    if result == 0:
        # do what you want to do
        print u"重復(fù)"
    else:
        # do what you want to do
        print u"不重復(fù)"
    redis_close(pool)

def redis_init(parasecname="Redis"):
    """
    初始化redis
    :param parasecname:
    :return: redis連接池
    """
    cur_script_dir = os.path.split(os.path.realpath(__file__))[0]
    cfg_path = os.path.join(cur_script_dir, "db.conf")

    cfg_reder = ConfigParser.ConfigParser()
    secname = parasecname
    cfg_reder.readfp(codecs.open(cfg_path, "r", "utf_8"))
    redis_host = cfg_reder.get(secname, "server")
    redis_pass = cfg_reder.get(secname, "pass")

    # redis
    pool = redis.ConnectionPool(host=redis_host, port=6379, db=0, password=redis_pass)
    r = redis.Redis(connection_pool=pool)

    return pool, r

def sha1(x):
    sha1obj = hashlib.sha1()
    sha1obj.update(x)
    hash_value = sha1obj.hexdigest()
    return hash_value

def check_repeate(r, check_str, set_name):
    """
    向redis集合中添加元素涂身,重復(fù)則返回0,不重復(fù)則添加成功搓蚪,并返回1
    :param r:redis連接
    :param check_str:被添加的字符串
    :param set_name:項目所使用的集合名稱蛤售,建議如下格式:”projectname:task_remove_repeate“
    :return:
    """
    hash_value = sha1(check_str)
    result = r.sadd(set_name, hash_value)
    return result

def redis_close(pool):
    """
    釋放redis連接池
    :param pool:
    :return:
    """
    pool.disconnect()

if __name__ == '__main__':
    example()

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市妒潭,隨后出現(xiàn)的幾起案子悴能,更是在濱河造成了極大的恐慌,老刑警劉巖杜耙,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件搜骡,死亡現(xiàn)場離奇詭異,居然都是意外死亡佑女,警方通過查閱死者的電腦和手機记靡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進店門谈竿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人摸吠,你說我怎么就攤上這事空凸。” “怎么了寸痢?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵呀洲,是天一觀的道長。 經(jīng)常有香客問我啼止,道長道逗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任献烦,我火速辦了婚禮滓窍,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘巩那。我一直安慰自己吏夯,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布即横。 她就那樣靜靜地躺著噪生,像睡著了一般。 火紅的嫁衣襯著肌膚如雪东囚。 梳的紋絲不亂的頭發(fā)上跺嗽,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天,我揣著相機與錄音页藻,去河邊找鬼抛蚁。 笑死,一個胖子當(dāng)著我的面吹牛惕橙,可吹牛的內(nèi)容都是我干的瞧甩。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼弥鹦,長吁一口氣:“原來是場噩夢啊……” “哼肚逸!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起彬坏,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤朦促,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后栓始,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體务冕,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年幻赚,在試婚紗的時候發(fā)現(xiàn)自己被綠了禀忆。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片臊旭。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖箩退,靈堂內(nèi)的尸體忽然破棺而出离熏,到底是詐尸還是另有隱情,我是刑警寧澤戴涝,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布滋戳,位于F島的核電站,受9級特大地震影響啥刻,放射性物質(zhì)發(fā)生泄漏奸鸯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一可帽、第九天 我趴在偏房一處隱蔽的房頂上張望府喳。 院中可真熱鬧,春花似錦蘑拯、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至孔轴,卻和暖如春剃法,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背路鹰。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工贷洲, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人晋柱。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓优构,卻偏偏與公主長得像,于是被迫代替她去往敵國和親雁竞。 傳聞我的和親對象是個殘疾皇子钦椭,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,092評論 2 355

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)碑诉,斷路器彪腔,智...
    卡卡羅2017閱讀 134,672評論 18 139
  • 本文將從Redis的基本特性入手德挣,通過講述Redis的數(shù)據(jù)結(jié)構(gòu)和主要命令對Redis的基本能力進行直觀介紹。之后概...
    kelgon閱讀 61,169評論 23 625
  • 1 Redis介紹1.1 什么是NoSql為了解決高并發(fā)番挺、高可擴展、高可用吗浩、大數(shù)據(jù)存儲問題而產(chǎn)生的數(shù)據(jù)庫解決方...
    克魯?shù)吕?/span>閱讀 5,297評論 0 36
  • 艾斯壓陣 一盞燈建芙, 一片昏黃; 一簡書懂扼, 一杯淡茶禁荸。 守著那一份淡定, 品讀屬于自己的寂寞阀湿。 保持淡定赶熟, 才能欣賞...
    審判spp閱讀 36,487評論 0 5