[Python3.4]通过Redis利用BloomFilter实现数据去重

写爬虫的时候需要解决的一个很重要的问题就是需要判断得来的新链接是否之前已经爬过。如果已经爬过,则没有必要再爬。我之前采用的是非常笨拙的方法,就是把所有已经爬过的地址放在mysql的一张表中,但是问题在于,这样每一个新链接到来,都会查询一次是否该链接在表格中。这样的话,单单查询过程就会耗费磁盘大量的读写性能。而且实际运行的过程中也发现,磁盘的读取速率是写入速率的10倍以上,这显然是不可接受的。
一个可行的改进方案是使用内存数据库作为mysql的缓存。这里选用的是redis,是一种键值型数据库。通过将需要频繁查询的内容读入Redis,这样可以直接通过redis查询是否该链接已经存在,从而避免了直接从磁盘读取数据,提高读写性能。

——————————资料库————————————
●redis官网 点我
●然而,redis官方并不支持windows(你们这是对软狗的歧视,哼!(╯‵□′)╯︵┻━┻)所以像我这样想在win下使用的,可以去找Microsoft Open Tech group在github下的一个64位版本。 点我点我
●基础设置教程:点我点我点我
●指令教程(bloomfilter主要通过setbit和getbit来实现)点我
——————————↑↑↑↑↑↑————————————

有个问题是,把所有数据都读入内存是不可行的,因为数据量太大,而内存太小。所以这就需要bloomfilter出场了. 简单的说,bloomfilter是通过多个hash函数,将字符串映射到不同的比特位。通过查询相应的比特位上的值是否全为1,来判断该数据是否已存入数据库中。值得注意的是,bloomfilter是有出错概率的。简单的说就是:
如果bloomfilter判断不存在,则一定不存在
如果bloomfilter判断存在,则可能不存在
看完发现简直是为爬虫量身定制啊有没有!对于爬虫而言,出错的代价微乎其微,大不了少爬几个就是了,反正不会重复爬。

bloomfilter介绍:这里

对于python2.7来说,好像有个叫pybloomfilter的库可以用。但那个是单线程的,当需要多线程合作时就不行了,而且不太适合3.4版本。所以我对网上别人写的针对3.4版本的小程序稍加改进,使之能够适合redis.

import redis

class SimpleHash():
    def __init__(self,cap,seed):
        self.cap=cap
        self.seed=seed
    def hash(self,value):
        ret=0
        for i in range(value.__len__()):
            ret+=self.seed*ret+ord(value[i])
        return ((self.cap-1) & ret)

class BloomFilter():
    def __init__(self):
        self.bit_size=1<<25
        self.seeds=[5,7,11,13,31,37,61]
        self.r=redis.StrictRedis(host='127.0.0.1',port=6379,db=0)
        self.hashFunc=[]
        for i in range(self.seeds.__len__()):
            self.hashFunc.append(SimpleHash(self.bit_size,self.seeds[i]))

    def isContains(self,str_input,name):
        if str_input==None:
            return False
        if str_input.__len__()==0:
            return False
        ret=True
        for f in self.hashFunc:
            loc=f.hash(str_input)
            ret=ret & self.r.getbit(name,loc)
        return ret

    def insert(self,str_input,name):
        for f in self.hashFunc:
            loc=f.hash(str_input)
            self.r.setbit(name,loc,1)

uid=['alskdjflkasjdf','kajdsklfjlkasdf','lhjkkjhrwqer','alskdjflkasjdf']
bf=BloomFilter()
err_time=0
for id in uid:
    if bf.isContains(id,'test'):
        err_time+=1
    else:
        bf.insert(id,'test')
print(err_time)
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python RedisBloom是一个用于在Redis实现布隆过滤器的Python库。这个库提供了一种简洁而高效的方法来过滤重复的数据或判断元素是否存在。通过使用Redis自带的setbit方法和多个哈希函数,Python RedisBloom可以将字符串映射到不同的比特位,并在查询时判断相应的比特位上的值来确定元素是否存在。 一个使用Python RedisBloom的示例是,可以创建一个ReBloomFilter类来封装操作Redis中的布隆过滤器。在初始化时,可以传入一个哈希列表和容量参数,然后在exists方法中使用哈希列表对元素进行判断,如果任何一个哈希函数返回False,说明元素不存在。而在add方法中,可以使用哈希列表对元素进行哈希并在Redis中设置相应的比特位为1来表示元素的存在。 另外,Python RedisBloom在处理大量数据时也非常适用,因为它可以将数据分散在多个比特位上,从而减少内存占用。这对于爬虫等需要处理大量数据的应用非常有帮助。 总之,Python RedisBloom是一个方便而高效的Python库,可以实现布隆过滤器功能,并且在处理大量数据时更加节省内存。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [pythonRedis实现简单布隆过滤器 BloomFilter](https://blog.csdn.net/milanla/article/details/119814700)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [xml文件批量处理python脚本](https://download.csdn.net/download/caoxinri123/88239057)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [[Python3.4]通过Redis利用BloomFilter实现数据去重](https://blog.csdn.net/u014595019/article/details/50324167)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值