位图:如何实现网页爬虫中的URL去重功能

位图:如何实现网页爬虫中的URL去重功能?

爬虫的工作原理是通过解析已经爬取页面中的网页链接,然后再爬取这些链接对应的网页,而同一个网页链接可能被包含在多个页面中,会导致爬虫在爬取的过程中重复爬取相同的网页,如何避免重复的爬取?

记录已经爬取的网页链接URL,在爬取新的网页之前,拿它的链接,在 已经爬取的网页链接列表中搜索。如何记录已经爬取的网页链接?需要用什么数据结构?

算法解析

需要处理的对象是网页链接,需要支持的操作是添加一个URL和查询一个URL

存储这些网页链接,可以存储在散列表中,分治+散列表的思路是可以的,能否优化?

想在内存方面有节省,可以使用布隆过滤器,布隆过滤器本身是基于位图的。我们有1000W个整数,整数范围在1到1亿之间,如何快速查找某个整数是否在这1000万个整数中?

申请一个大小为1亿、数据类型为布尔类型(true or false)的数组,将这1000万个整数作为数组下标,将对应的数组值设置成true,如整数5对应下标为5的数组值为true,即array[5] = true,当我们查询某个整数K是否在这1000万个整数中的时候,只需要将对应的数组值array[K]取出来,看是否等于true,如果等于true,说明1000万中包含整数K。表示true or false 两个值,只需要用一个二进制位bit即可,如如何通过编程语言表示一个二进制位?

public class BitMap{   //Java中char类型占16 bit,即使2个字节
	private char[] bytes;
	private int nbits;
	
	public BitMap(int nbits){
		this.nbits = nbits;
		this.bytes = new char[nbits/16+1];
	}
	
	public void set(int k ){
		if(k > nbits) return ; 
		int byteIndex = k /16;
		int bitIndex = k % 16;
		bytes[byteIndex] |= (1 << bitIndex);
	}
	
	public boolean get(int k ){
		if( k > nbits)  return false;
		int byteIndex = k / 16;
		int bitIndex = k % 16;
		return (bytes[byteIndex] & (1 << bitIndex)) != 0;
	}
}

位图通过数组下标来定位数据,所以访问速度很高,每个数字用一个二进制位来表示,在数字范围不大的情况下,需要的内存空间很节省

如果范围很大,1到10亿,就是用布隆过滤器,如数据个数是1000万,范围是1到10亿,仍然使用一个1亿个二进制大小的位图,通过哈希函数,对数字进行处理,落在1到1亿的范围内,比如把哈希函数设计成f(x) = x%n,x表示数字,n表示位图大小。布隆过滤器的操作是:

使用K个哈希函数,对同一个数字进行求哈希值,得到K个不同的哈希值,记作X1,X2,X3…XK,把这K个数字作为位图的下标,对应BitMap[x1]、BitMap[x2]、BitMap[x3]、…、BitMap[xk]都设置为true,用K个二进制位表示一个数字的存在,当查询某个数组是否存在的时候用童颜的K个哈希函数,对这个数字求哈希值,得到Y1 Y2 Y3 …Yk,看这K个哈希值是否都为true

不用的数字经过一个哈希函数处理后,可能会产生相同的哈希值,但是经过K个哈希函数处理之后,K个哈希值都相同的概率很低了,但是可能会产生误判,但只会对存在的情况产生误判,如果某个数字经过布隆过滤器判断存在可能会产生误判,只需要调整哈希函数的个数、位图大小跟要存储数组的个数之间的比例,这误判的概率会很低

我们用布隆过滤器来记录已经爬取过的URL,如果要判重的网页有10亿个,可以用一个10倍大小的位图来存储,就是100亿个二进制位,就是1.2GB,而且,布隆过滤器使用多个哈希函数对同一个网页链接处理,CPU只需要将URL从内存中读取依次,进行多次哈希计算,这个判重方式会更加快速

总结引申

布隆过滤器有误判率,跟哈希函数个数、位图大小有关,无法事先知道判重数据个数情况,需要支持自动扩容的功能,当数据个数与位图大小的比例超过某个阈值的时候申请重新一个新的位图

如果有1亿个整数,数据范围从1到10亿,如何快速并省内存的给这1亿个数据从小到大排序?

使用位图算法:范围1到10亿,用位图存储125M,将1亿个数字依次添加到位图中农,将位图按下标从小到大输出值为1 的下标

发布了75 篇原创文章 · 获赞 9 · 访问量 9173

猜你喜欢

转载自blog.csdn.net/ywangjiyl/article/details/104729734
今日推荐