在爬虫启动工作的过程中,我们不希望同一个网页被多次下载,因为重复下载不仅会浪费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函数进行映射,映射到一个二进制向量上,这种方式充分利用了比特位。
不过,我没有用过这种方式,有机会可以尝试一下。
可以参考Google的
- http://www.googlechinablog.com/2007/07/bloom-filter.html
转自:
- http://hi.baidu.com/shirdrn/blog/item/40ed0fb1ceac4d5c0923029d.html
分享到:
相关推荐
(5) 可能会进行URL去重和深度控制;(6) 存储数据。在这个项目中,`mySpider`类很可能包含了这些功能的实现。 **5. 第三方库的使用** 描述中提到,项目需要导入第三方包。对于Java网络爬虫,可能会用到如Jsoup库进行...
【标题】: "关于spider网络爬虫的程序,用于搜索" 网络爬虫,或称为“蜘蛛”(Spider),是互联网上的一种自动化程序,它的主要任务是遍历Web页面,抓取并存储网页内容,以便进行后续的数据分析或构建搜索引擎。在...
传统的网络爬虫会遍历整个网站,下载所有页面,但这种方法对于大型网站来说既耗时又浪费资源。增量爬虫则只抓取新出现或更新过的页面,这样可以大大减少爬取时间和存储需求。实现增量爬虫的关键在于跟踪和识别网页的...
### Java编写的网络爬虫(Crawler/Spider)关键知识点解析 #### 一、网络爬虫(Crawler/Spider)概述 网络爬虫(Web Crawler),也称为网页蜘蛛、网络机器人等,是一种按照一定的规则自动抓取万维网信息的程序或者脚本...
4. **URL去重**:使用哈希表或布隆过滤器来检测和去除重复的URL。 5. **IP代理**:为了避免因频繁请求被目标网站封禁,Spider可能需要使用代理IP进行访问。 6. **爬虫框架**:如Python的Scrapy,提供了一整套的...
- **URL去重**:使用`HashMap`来存储已抓取的URL,避免重复抓取同一个页面。 - **层级限制**:限制抓取的深度,防止无限递归导致资源消耗过大。 综上所述,这个网络爬虫示例代码虽然较为基础,但包含了网络爬虫的...
项目名称暗示了它可能是一个快速、灵活的爬虫框架,设计用于模拟蜗牛(snail)缓慢而坚定地遍历网页,同时结合了spider(蜘蛛)的网络爬行特性。这个开源项目很可能包含了一系列的模块和功能,如URL管理器、下载器、...
具体章节包括爬虫的基本原理、URL去重、网页解析、Scrapy框架的介绍、数据存储方法,以及通过Selenium处理动态内容。 3. 爬虫基本原理 网络爬虫通过模拟用户浏览行为,自动遍历网页,抓取所需信息。主要步骤包括...
本论文设计的分布式网络爬虫采用了广度优先搜索策略,通过页面分析算法来过滤无关URL,提高爬虫效率。系统架构采用主从模式,适合于中小规模的分布式系统,其中主节点负责总体调度,从节点专注于爬取任务,通信效率...
5. **URL去重与调度**:为了避免重复抓取同一网页,爬虫需要具备URL去重机制。同时,根据预设策略(如深度优先、广度优先)对URL队列进行调度,决定下一次抓取的顺序。 6. **内容存储**:抓取到的网页内容会存储在...
2. **URL去重**:为了避免重复爬取同一页面,系统需要在抓取URL时进行去重。Redis的集合(Set)数据结构可以用来存储已访问的URL,确保唯一性。 3. **负载均衡**:根据节点的负载情况动态分配任务,避免某个节点...
4. **URL去重**:为了避免重复抓取同一个页面,需要对抓取的URL进行去重处理。 5. **深度控制**:设置爬虫的爬取深度,防止无限循环或资源浪费。 6. **内容存储**:将抓取的页面内容存储到本地,便于后续的分析和...
标签进一步明确了这个项目的核心技术,即Bloom Filter在爬虫中的应用,表明该项目重点研究如何在爬虫中利用Bloom Filter进行有效的URL去重。 **文件列表:spider.c、bloomfilter.h、queue.h** - **spider.c**:这...
然而,实际的网络爬虫可能还需要处理更多复杂情况,如错误处理、URL去重、下载延迟、用户代理伪装、cookies管理、HTML解析、反爬策略等。此外,此代码未包含网页内容解析和存储的逻辑,这部分通常是网络爬虫的重点,...
在实际实现网络爬虫时,一个基本的框架可能包括创建Spider类,定义初始化方法,设定爬取目标(如特定贴吧的URL),使用requests库发送请求,然后利用BeautifulSoup或Lxml解析网页,提取所需信息,最后进行数据存储。...
网络爬虫源代码解析 本文将对网络爬虫源代码进行详细的解析,了解爬虫的实现机制和关键技术要点。 爬虫的基本概念 网络爬虫是一种自动化程序,用于从互联网上抓取和提取数据。爬虫可以根据特定的规则和算法来抓取...
4. **URL去重与队列管理**:为了避免重复抓取同一页面,爬虫会检查新提取的URL是否已存在于抓取队列中。如果不在,就将其加入队列,准备下一次抓取。 5. **深度优先/广度优先策略**:爬虫可以按照深度优先或广度...
URL去重是爬虫的基本功能,防止对同一个网页的多次访问,通常通过哈希表或布隆过滤器来实现。这些数据结构可以高效地检测已访问过的URL,避免无效的网络请求。 通用正文抽取算法是提取网页中有效信息的关键。因为...