布隆过滤器是什么?

在爬虫爬取网页的时候,我们会做的一件事情是判断这个网页是否之前已经爬取过。这个检验步骤在之前的文章里我是用了一个#集合#来保存已经爬取过的网页,而在计算机当中,使用hash表来保存。Hash表的好处就是能够快速定位,而它的缺点也众所皆知,就是存储空间的浪费。
为什么会浪费存储空间呢?

  • 哈希表方法需要把实实在在的具有特定长度的元素的信息指纹存储在内存或硬盘中的哈希表中(比如每个Email地址对应成一个8字节的信息指纹),这个存储量在实际应用中一般是相当大的。比如每存储一亿个Email地址,需要0.8G大小的数字指纹存储空间,考虑到哈希表的存储空间利用率一般只有一半,所以需要1.6G的存储空间。如果存储几十亿上百亿的Email地址,那就需要百亿字节的内存存储空间。
    为了解决空间浪费严重这一问题,我们采用布隆过滤器。

布隆过滤器实际上是一个很长的二进制向量和一系列的随机映射函数。

布隆过滤器是N位的二进制数组,其中N是位数组的大小。它还有另一个参数k,表示使用哈希函数的个数。这些哈希函数用来设置位数组的值。当往过滤器中插入元素x时,h1(x), h2(x), …, hk(x)所对应索引位置的值被置“1”,索引值由各个哈希函数计算得到。注意,如果我们增加哈希函数的数量,误报的概率会趋近于0.但是,插入和查找的时间开销更大,布隆过滤器的容量也会减小。

为了用布隆过滤器检验元素是否存在,我们需要校验是否所有的位置都被置“1”,与我们插入元素的过程非常相似。如果所有位置都被置“1”,那也就意味着该元素很有可能存在于布隆过滤器中。若有位置未被置“1”,那该元素一定不存在。

误报

示意图

以上图为例,具体的操作流程:假设集合里面有3个元素{x, y, z},哈希函数的个数为3。首先将位数组进行初始化,将里面每个位都设置位0。对于集合里面的每一个元素,将元素依次通过3个哈希函数进行映射,每次映射都会产生一个哈希值,这个值对应位数组上面的一个点,然后将位数组对应的位置标记为1。查询W元素是否存在集合中的时候,同样的方法将W通过哈希映射到位数组上的3个点。如果3个点的其中有一个点不为1,则可以判断该元素一定不存在集合中。反之,如果3个点都为1,则该元素可能存在集合中。注意:此处不能判断该元素是否一定存在集合中,可能存在一定的误判率。可以从图中可以看到:假设某个元素通过映射对应下标为4,5,6这3个点。虽然这3个点都为1,但是很明显这3个点是不同元素经过哈希得到的位置,因此这种情况说明元素虽然不在集合中,也可能对应的都是1,这是误判率存在的原因。

from bitarray import bitarrayimport mmh3class BloomFilter(set):def __init__(self,size,hash_count):#size:the num of the bitarray#hash_count:the num of hash functionsuper(BloomFilter,self).__init__()self.bit_array = bitarray(size)self.bit_array.setall(0) #初始化为0self.size = sizeself.hash_count = hash_countdef __len__(self):return self.sizedef __iter__(self):return iter(self.bit_array)def add(self,item):for i in range(self.hash_count):index = mmh3.hash(item,i) % self.sizeself.bit_array[index] = 1return selfdef __contains__(self,item):out = Truefor i in range(self.hash_count):index = mmh3.hash(item,i)%self.sizeif bit_array[index] == 0:out = Falsereturn outdef main():bloom = BloomFilter(100,5)fd = open("urls.txt")  #有重复的网址 http://www.kalsey.com/tools/buttonmaker/  bloomfilter = BloomFilter(100,10)    while True:    url = fd.readline().strip()   if (url == 'exit') :  print ('complete and exit now')break    elif url not in bloomfilter:   bloomfilter.add(url)# print(url)    else:    print ('url :%s has exist' % url )if __name__ == '__main__':main()

urls.txt

http://sourceforge.net/robots.txt
http://sourceforge.net/
http://sourceforge.net/
http://sourceforge.net and https://sourceforge.net
http://sourceforge.net/sitemap.xml
http://sourceforge.net/allura_sitemap/sitemap.xml
http://sourceforge.net/directory_sitemap.xml
http://a.fsdn.com
http://a.fsdn.com/con/img/sftheme/favicon.ico
http://a.fsdn.com/con/js/min/sf.head.js
http://a.fsdn.com/con/js/sftheme/dd_belatedpng.js
http://fonts.googleapis.com
http://fonts.googleapis.com/css
http://a.fsdn.com/con/css/sf.css
http://sourceforge.net/blog/feed/
http://email.playtime.uni.cc/
http://services.nexodyne.com/email/
http://gizmo967.mgs3.org/Gmail/
http://www.hkwebs.net/catalog/tools/gmail/
http://sagittarius.dip.jp/~toshi/cgi-bin/designmail/designmail.html
http://www.eoool.com/
http://sourceforge.netand
https://sourceforge.net
http://a.fsdn.com/con/js/adframe.js
http://sourceforge.net/directory/
http://kalsey.com/tools/buttonmaker/
http://www.lucazappa.com/brilliantMaker/buttonImage.php
http://www.feedforall.com/public/rss-graphic-tool.htm
http://www.yugatech.com/make.php
http://www.hkwebs.net/catalog/tools/buttonmaker/index.php
http://phorum.com.tw/Generator.aspx
http://www.logoyes.com/lc_leftframe.htm
http://cooltext.com/Default.aspx
http://kalsey.com/tools/buttonmaker/
exit

代码运行结果:

运行结果

布隆过滤器的缺点:

  • 无法返回元素本身
    布隆过滤器并不会保存插入元素的内容,只能检索某个元素是否存在。
  • 删除某个元素
    想从布隆过滤器中删除某个元素可不是一件容易的事情,你无法撤回某次插入操作,因为不同项目的哈希结果可以被索引在同一位置。

代码戳:https://github.com/GreenGitHuber/Web/tree/master/crawler

https://blog.csdn.net/a1368783069/article/details/52137417

url去重:布隆过滤器-python实现相关推荐

  1. URL 去重的 6 种方案!(附详细代码)

    来源 | Java中文社群(ID:javacn666) URL 去重在我们日常工作中和面试中很常遇到,比如这些: 可以看出,包括阿里,网易云.优酷.作业帮等知名互联网公司都出现过类似的面试题,而且和 ...

  2. 算法练习day12——190331(哈希函数、哈希表、布隆过滤器、一致性哈希)

    1.哈希函数 1.1 特点: 经典的哈希函数输入域是无穷大的. 输出域是有穷尽的: 相同输入得到的输出肯定是一样的: 不同的输入得到的输出也可能一样(输入域>输出域); 哈希函数的离散型:给定多 ...

  3. 【恋上数据结构】布隆过滤器(Bloom Filter)原理及实现

    布隆过滤器(Bloom Filter) 引出布隆过滤器(判断元素是否存在) 布隆过滤器介绍(概率型数据结构) 布隆过滤器的原理(二进制 + 哈希函数) 布隆过滤器的误判率(公式) 布隆过滤器的实现 布 ...

  4. 网络爬虫:URL去重策略之布隆过滤器(BloomFilter)的使用

    前言: 最近被网络爬虫中的去重策略所困扰.使用一些其他的"理想"的去重策略,不过在运行过程中总是会不太听话.不过当我发现了BloomFilter这个东西的时候,的确,这里是我目前找 ...

  5. scrapy去重原理,scrapy_redis去重原理和布隆过滤器的使用

    1.去重的应用场景: 如果你只是做一些简单的爬虫,可能不会遇到这种问题,可是如果你正在做一个大型的全站爬虫,或是一个持久化的爬虫,那你一定会遇到这样的问题:刚开始爬虫速度还可以,随着待爬取的队列达到数 ...

  6. 三十七 Python分布式爬虫打造搜索引擎Scrapy精讲—将bloomfilter(布隆过滤器)集成到scrapy-redis中...

    Python分布式爬虫打造搜索引擎Scrapy精讲-将bloomfilter(布隆过滤器)集成到scrapy-redis中,判断URL是否重复 布隆过滤器(Bloom Filter)详解 基本概念 如 ...

  7. python爬虫去重_Python网络爬虫(7):URL去重

    摘要:从零开始写爬虫,初学者的速成指南! 封面: image 本期我们来聊聊URL去重那些事儿.以前我们曾使用Python的字典来保存抓取过的URL,目的是将重复抓取的URL去除,避免多次抓取同一网页 ...

  8. python redis 布隆过滤器实现

    布隆过滤器是什么? 如果想判断一个元素是不是在一个集合里,一般想到的是将集合中所有元素保存起来,然后通过比较确定.链表.树.散列表(又叫哈希表,Hash table)等等数据结构都是这种思路.但是随着 ...

  9. 一道腾讯面试题:如何快速判断某 URL 是否在 20 亿的网址 URL 集合中?布隆过滤器...

    何为布隆过滤器 还是以上面的例子为例: 判断逻辑: 多次哈希: Guava的BloomFilter 创建BloomFilter 最终还是调用: 使用: 算法特点 使用场景 假设遇到这样一个问题:一个网 ...

  10. url过滤怎么解除_腾讯面试官是这样来问布隆过滤器的?

    作者:张振伟来源:https://zhangzw.com/20190521.html 假设遇到这样一个问题:一个网站有 20 亿 url 存在一个黑名单中,这个黑名单要怎么存?若此时随便输入一个 ur ...

最新文章

  1. Bzoj2337:[HNOI2011]XOR和路径
  2. Spring AOP源码分析(八)SpringAOP要注意的地方
  3. ubuntu下最简单的MySQL安装教程
  4. 洗被套的时候洗衣机里面不要再放其他东西
  5. 丹鸟快递承诺达到不了怎么办_谈谈2019年快递行业的竞争
  6. SOL注入——基干联合查询的POST注入(四)
  7. 时间转化_Excel常见时间日期函数全讲解,10个函数教你如何进行日期转化
  8. httpd 服务的两个节点的HA
  9. 微软发布面向企业区块链网络的Coco Framework
  10. shared_ptr四宗罪
  11. open-falcon采集的一些指标及说明
  12. 某人说自己是佛菩萨转世,什么情况下才可信
  13. 人民币数字化将如何影响行业格局?
  14. 客户端安装SP3补丁包失败
  15. DHCP报文抓包分析
  16. Python_4_内置结构-元组-字符串-bytes-bytearray-切片
  17. Oracle11g数据库的下载与安装
  18. 光电对抗发现历史、内容、原理及发展趋势
  19. 51单片机如何延时1s,让LED灯闪烁
  20. Java:JSON解析工具-json-lib

热门文章

  1. 找出单身狗java_Java单身狗 —— 单例模式
  2. Flutter跨组件共享状态的利器Provider原理解析
  3. 嵌入式linux系统运行程序,嵌入式Linux系统启动过程
  4. 城市轨道交通运营管理属于什么院系_2020年报考山东交通职业学院城市轨道交通运营管理专业怎么样...
  5. python支持强大的科学计算功能_Python可以做什么——Python语言的一个简要导引
  6. 在计算机上的英语作文,我和电脑的英语作文
  7. gin框架-2-返回是html格式的网页数据
  8. 帆软FineMobile 自适应
  9. openfeign seata事务不回滚_Spring,你为何中止我的事务?
  10. python慢的原因_为什么 Python 这么慢?