爬虫技术之——bloom filter(含java代码)
来源:互联网 发布:octane for c4d mac 编辑:程序博客网 时间:2024/05/22 19:58
在爬虫系统中,在内存中维护着两个关于URL的队列,ToDo队列和Visited队列,ToDo队列存放的是爬虫从已经爬取的网页中解析出来的即将爬取的URL,但是网页是互联的,很可能解析出来的URL是已经爬取到的,因此需要VIsited队列来存放已经爬取过的URL。当爬虫从ToDo队列中取出一个URL的时候,先和Visited队列中的URL进行对比,确认此URL没有被爬取后就可以下载分析来。否则舍弃此URL,从Todo队列取出下一个URL继续工作。
然后,我们知道爬虫在爬取网页时,网页的量是比较大的,直接将所有的URL直接放入Visited队列是很浪费空间的。因此引入bloom filter!
我们把bloom filer设置为m个bit,全部初始为0。
对每一个URL,进行K(K<m)次相互独立的哈希,一共得到K个值,将这K个值在bloom filter中对应的bit位置1。
经过上述处理的bloom filter实际上构成了我们所说的Visited队列,当我们从ToDo队列中取出一个新的URL时,同样,进行相同的K次哈希,每进行一次哈希,查看bloom filter中对应位,只要发现某位是0,就可以确定这个URL是没有处理过的,可以继续下载处理。
那么,原理清楚之后,还有几个问题没有解决。
1、bloom filter是有可能发生错误的,因为不处理碰撞,也就是说,有可能把不属于这个集合的元素误认为属于这个集合
错误率的计算:
在n个URL都进行k次散列加入之后,bloomfilter中某位是0的概率
错误率(即一个新的URL恰好k次散列的值对应的位都已经是1的概率)
2、哈希函数个数K的确定
k = ln2· (m/n)时(具体数学分析见http://blog.csdn.net/jiaomeng/article/details/1495500)
3、bloomfilter位数M的确定
我们可以想到,M的大小越大,错误率就会越小,但是数学证明给出了一个下界。即M = log2 e N = 1.44N。
附上java代码
1 /**屈永泉 布隆过滤器 快速确定哪些网页已经被下载过*/ 2 3 package crawler; 4 5 import java.util.BitSet; 6 7 public class BloomFilter { 8 private int defaultSize = 5000 << 10000; 9 private int basic = defaultSize - 1;10 private BitSet bits = new BitSet(defaultSize);11 12 private int[] lrandom(String key) { // 产生八个随机数并返回13 int[] randomsum = new int[8];14 for (int i = 0; i < 8; i++)15 randomsum[0] = hashCode(key, i + 1);16 return randomsum;17 }18 19 // 将一个URL加入20 public synchronized void add(String key) {21 int keyCode[] = lrandom(key);22 for (int i = 0; i < 8; i++)23 bits.set(keyCode[i]); // 将指定索引处的位设置为 true24 }25 }26 27 // 判断一个URL是否存在28 public boolean exist(String key) {29 int keyCode[] = lrandom(key);30 if (bits.get(keyCode[0])31 && bits.get(keyCode[1]) // 返回指定索引处的位值。32 && bits.get(keyCode[2]) && bits.get(keyCode[3])33 && bits.get(keyCode[4]) && bits.get(keyCode[5])34 && bits.get(keyCode[6]) && bits.get(keyCode[7])) {35 return true;36 }37 return false;38 }39 40 41 private int hashCode(String key, int Q) {42 int h = 0;43 int off = 0;44 char val[] = key.toCharArray(); // 将此URl转换为一个新的字符数组45 int len = key.length();46 for (int i = 0; i < len; i++) {47 h = (30 + Q) * h + val[off++];48 }49 return basic & h;50 }51 52 53 /* public static void main(String[] args) { // TODO Auto-generated method54 long pre = 0;55 long post = 0;56 pre = System.nanoTime();57 BloomFilter f = new BloomFilter(); //初始化58 f.add("http://www.agrilink.cn/"); f.add("http://www.baidu.com/");59 System.out.println(f.exist("http://www.baidu.com/"));60 System.out.println(f.exist("http://www.baidud.com/"));61 post = System.nanoTime();62 System.out.println("Time: " + (post - pre));63 64 }65 */66 67 }
- 爬虫技术之——bloom filter(含java代码)
- 爬虫 —— 布隆过滤器算法(Bloom Filter)
- BLOOM FILTER —读数学之美
- 【算法技术】小智慧,大作为——Bloom Filter
- java 爬虫使用Bloom Filter 算法实现Visited表
- 数学之美系列—布隆过滤器(Bloom Filter)
- 海量数据处理专题(二)——Bloom Filter
- 海量数据处理专题(二)——Bloom Filter
- 海量数据处理专题(二)——Bloom Filter
- 海量数据处理专题(二)——Bloom Filter
- 海量数据处理专题(二)——Bloom Filter
- 海量数据处理专题(二)——Bloom Filter
- 海量数据处理专题(二)——Bloom Filter
- 海量数据处理专题(二)——Bloom Filter
- 初步认识bloom filter(布隆过滤器)以及java实现代码
- Bloom Filter 系列改进之Bloom Tree
- Bloom Filter概念,原理,代码。。
- Bloom Filter——大规模数据处理利器
- Core Animation之多种动画效果
- C++文件(夹)选择对话框
- 设备驱动(十六)
- Eclipse与Android源码中ProGuard工具的使用
- 浅论Android网络请求库——android-async-http
- 爬虫技术之——bloom filter(含java代码)
- ajax在easyui里面的应用举例2-登录验证
- 设备驱动(十七)
- Java面向对象——MyEclipse快捷键使用手册
- Oracle RAC Failover 详解
- Android -- 获取正在运行的service信息
- 星际战术白皮书之人族战术大全
- ADVANCED FLEX 4
- 重绘CListCtrl列表中,WM_LBUTTONDOWN按下以后处理WM_LBUTTONUP情况