网络爬虫设计——URL去重存储库设计
来源:互联网 发布:天涯明月刀包子脸数据 编辑:程序博客网 时间:2024/05/23 20:31
在爬虫启动工作的过程中,我们不希望同一个网页被多次下载,因为重复下载不仅会浪费CPU机时,还会为搜索引擎系统增加负荷。而想要控制这种重复性下载问题,就要考虑下载所依据的超链接,只要能够控制待下载的URL不重复,基本可以解决同一个网页重复下载的问题。
非常容易想到,在搜索引擎系统中建立一个全局的专门用来检测,是否某一个URL对应的网页文件曾经被下载过的URL存储库,这就是方案。
接着要考虑的就是如何能够更加高效地让爬虫工作,确切地说,让去重工作更加高效。如果实现去重,一定是建立一个URL存储库,并且已经下载完成的URL在进行检测时候,要加载到内存中,在内存中进行检测一定会比直接从磁盘上读取速度快很多。
我们先从最简单的情况说起,然后逐步优化,最终得到一个非常不错的解决方案。
第一,基于磁盘的顺序存储。
这里,就是指把每个已经下载过的URL进行顺序存储。你可以把全部已经下载完成的URL存放到磁盘记事本文件中。每次有一个爬虫线程得到一个任务URL开始下载之前,通过到磁盘上的该文件中检索,如果没有出现过,则将这个新的URL写入记事本的最后一行,否则就放弃该URL的下载。
这种方式几乎没有人考虑使用了,但是这种检查的思想是非常直观的。试想,如果已经下载了100亿网页,那么对应着100亿个链接,也就是这个检查URL是否重复的记事本文件就要存储这100亿URL,况且,很多URL字符串的长度也不小,占用存储空间不说,查找效率超级低下,这种方案肯定放弃。
第二,基于Hash算法的存储。
对每一个给定的URL,都是用一个已经建立好的Hash函数,映射到某个物理地址上。当需要进行检测URL是否重复的时候,只需要将这个URL进行Hash映射,如果得到的地址已经存在,说明已经被下载过,放弃下载,否则,将该URL及其Hash地址作为键值对存放到Hash表中。
这样,URL去重存储库就是要维护一个Hash表,如果Hash函数设计的不好,在进行映射的时候,发生碰撞的几率很大,则再进行碰撞的处理也非常复杂。而且,这里使用的是URL作为键,URL字符串也占用了很大的存储空间。
第三,基于MD5压缩映射的存储。
MD5算法是一种加密算法,同时它也是基于Hash的算法。这样就可以对URL字符串进行压缩,得到一个压缩字符串,同时可以直接得到一个Hash地址。另外,MD5算法能够将任何字符串压缩为128位整数,并映射为物理地址,而且MD5进行Hash映射碰撞的几率非常小,这点非常好。从另一个方面来说,非常少的碰撞,对于搜索引擎的爬虫是可以容忍的。况且,在爬虫进行检测的过程中,可以通过记录日志来保存在进行MD5时发生碰撞的URL,通过单独对该URL进行处理也是可行的。
下面就是是对URL进行压缩的MD5方法,对URL字符串进行压缩:
public static String md5(String string) {char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd','e', 'f' };try {byte[] bytes = string.getBytes();MessageDigest messageDigest = MessageDigest.getInstance("MD5");messageDigest.update(bytes);byte[] updateBytes = messageDigest.digest();int len = updateBytes.length;char myChar[] = new char[len * 2];int k = 0;for (int i = 0; i < len; i++) {byte byte0 = updateBytes[i];myChar[k++] = hexDigits[byte0 >>> 4 & 0x0f];myChar[k++] = hexDigits[byte0 & 0x0f];}return new String(myChar);} catch (Exception e) {return null;}}
在Java中有一个Map类非常好,你可以将压缩后的URL串作为Key,而将Boolean作为Value进行存储,然后将工作中的Map在爬虫停止工作后序列化到本地磁盘上;当下一次启动新的爬虫任务的时候,再将这个Map反序列化到内存中,供爬虫进行URL去重检测。
第四,基于嵌入式Berkeley DB的存储。
Berkeley DB的特点就是只存储键值对类型数据,这和URL去重有很大关系。去重,可以考虑对某个键,存在一个值,这个值就是那个键的状态。
使用了Berkeley DB,你就不需要考虑进行磁盘IO操作的性能损失了,这个数据库在设计的时候很好地考虑了这些问题,并且该数据库支持高并发,支持记录的顺序存储和随机存储,是一个不错的选择。
URL去重存储库使用Berkeley DB,压缩后的URL字符串作为Key,或者直接使用压缩后的URL字节数组作为Key,对于Value可以使用Boolean,一个字节,或者使用字节数组,实际Value只是一个状态标识,减少Value存储占用存储空间。
第五,基于布隆过滤器(Bloom Filter)的存储。
使用布隆过滤器,设计多个Hash函数,也就是对每个字符串进行映射是经过多个Hash函数进行映射,映射到一个二进制向量上,这种方式充分利用了比特位。
- 网络爬虫设计——URL去重存储库设计
- 网络爬虫设计——URL去重存储库设计
- 网络爬虫-URL去重
- 网络爬虫URL去重
- 网络爬虫-URL去重
- 网络爬虫去重参考
- 网络爬虫URL消重
- 爬虫应用-bloomfilter-URL去重
- 网络爬虫:URL去重策略之布隆过滤器(BloomFilter)的使用
- 网络爬虫:URL去重策略之布隆过滤器(BloomFilter)的使用
- 网络爬虫:URL去重策略之布隆过滤器(BloomFilter)的使用
- Java网络爬虫(九)--海量URL去重之布隆过滤器
- Linux企业级项目实践之网络爬虫(3)——设计自己的网络爬虫
- 网络爬虫的设计——参考larbin
- 网络爬虫的设计分析
- DHT网络存储设计
- 爬虫去重策略
- 文本相似度检测(网络爬虫去重算法)
- 红黑树插入某个节点的方法
- UNIX网络编程——shutdown 与 close 函数 的区别
- C++中内部函数(静态函数)和外部函数的用法
- shape drawable 翻译
- 关于比赛
- 网络爬虫设计——URL去重存储库设计
- 10.网络编程之三
- 用GDB调试程序(二)
- 九度-1168 字符串的查找删除
- 有关webkit-gtk
- windows phone 8学习1
- cocos2d-x商业级单机游戏和网络游戏开发系列
- win7 设置眼睛保护色窗口
- 通知内核你的设备 不支持llseek, 通过在你的 open 方法中调用nonseekable_open