Heritrix3.3.0源码阅读 允许重复下载

Heritrix3.3.0的org.archive.crawler.datamodel.UriUniqFilter接口提供对下载的uri的唯一性保证,它的子类org.archive.crawler.util.SetBasedUriUniqFilter实现了保证发送到下载队列的uri的是唯一的方法:

    public void add(String key, CrawlURI value) {
        profileLog(key);
        if (setAdd(key)) {
            this.receiver.receive(value);
            if (setCount() % 50000 == 0) {
                LOGGER.log(Level.FINE, "count: " + setCount() + " totalDups: "
                        + duplicateCount + " recentDups: "
                        + (duplicateCount - duplicatesAtLastSample));
                duplicatesAtLastSample = duplicateCount;
            }
        } else {
            duplicateCount++;
        }
    }

只有当setAdd()方法返回true的时候,receiver才接受这个uri,也就是说,只有当这个uri没有被下载过,就把这个uri放入下载队列。我们只需要把这个方法改为下面这个样子,爬虫就不会拒绝下载那些曾经下载过的uri了:

    public void add(String key, CrawlURI value) {
        profileLog(key);
        // 实际上取消了重复判断
        boolean isDuplicate = false;
        if (!isDuplicate) {
            this.receiver.receive(value);
            if (setCount() % 50000 == 0) {
                LOGGER.log(Level.FINE, "count: " + setCount() + " totalDups: "
                        + duplicateCount + " recentDups: "
                        + (duplicateCount - duplicatesAtLastSample));
                duplicatesAtLastSample = duplicateCount;
            }
        } else {
            duplicateCount++;
        }
    }

这样的修改在你需要它是一个随时接受你的下载任务的而不是一个通常的爬虫时会很有用。
如果,你是采用的镜像下载方式,你还得修改org.archive.modules.writer.MirrorWriterProcessor的writeToPath(),因为该方法往磁盘上写文件时,如果目标文件之前已经存在,就会抛出异常。我们在该方法中添加检查目标文件是否存在的代码,如果存在,就将文件删除。修改后的方法如下:

private void writeToPath(RecordingInputStream recis, File dest)
        throws IOException {
        File tf = new File (dest.getPath() + "N");
        ReplayInputStream replayis = null;
        FileOutputStream fos = null;
        try {
            replayis = recis.getMessageBodyReplayInputStream();
            fos = new FileOutputStream(tf);

            // 添加的部分
            if (dest.isFile() && dest.exists()) {
                dest.delete();
            }

            replayis.readFullyTo(fos);
        } finally {
            IOUtils.closeQuietly(replayis);
            IOUtils.closeQuietly(fos);
        }
        if (!tf.renameTo(dest)) {
            throw new IOException("Can not rename " + tf.getAbsolutePath()
                                  + " to " + dest.getAbsolutePath());
        }

    }
Heritrix是一个开源,可扩展的web爬虫项目。用户可以使用它来从网上抓取想要的资源。Heritrix设计成严格按照robots.txt文件的排除指示和META robots标签。其最出色之处在于它良好的可扩展性,方便用户实现自己的抓取逻辑。 Heritrix是一个爬虫框架,其组织结构如图2.1所示,包含了整个组件和抓取流程: Heritrix采用的是模块化的设计,各个模块由一个控制器类(CrawlController类)来协调,控制器是整体的核心。控制器结构图如图2.2所示:   图2.2 CrawlController类结构图 CrawlController类是整个爬虫的总控制者,控制整个抓取工作的起点,决定整个抓取任务的开始和结束。CrawlController从Frontier获取URL,传递给线程池(ToePool)中的ToeThread处理。 Frontier(边界控制器)主要确定下一个将被处理的URL,负责访问的均衡处理,避免对某一Web服务器造成太大的压力。Frontier保存着爬虫的状态,包括已经找到的URI、正在处理中的URI和已经处理过的URI。 Heritrix是按多线程方式抓取的爬虫,主线程把任务分配给Teo线程(处理线程),每个Teo线程每次处理一个URL。Teo线程对每个URL执行一遍URL处理器链。URL处理器链包括如下5个处理步骤。整个流程都在图2.1中。 (1)预取链:主要是做一些准备工作,例如,对处理进行延迟和重新处理,否决随后的操作。 (2)提取链:主要是下载网页,进行DNS转换,填写请求和响应表单。 (3)抽取链:当提取完成时,抽取感兴趣的HTML和JavaScript,通常那里有新的要抓取的URL。 (4)写链:存储抓取结果,可以在这一步直接做全文索引。Heritrix提供了用ARC格式保存下载结果的ARCWriterProcessor实现。 (5)提交链:做和此URL相关操作的最后处理。检查哪些新提取出的URL在抓取范围内,然后把这些URL提交给Frontier。另外还会更新DNS缓存信息。 服务器缓存(Server cache)存放服务器的持久信息,能够被爬行部件随时查到,包括被抓取的Web服务器信息,例如DNS查询结果,也就是IP地址。 标签:Heritrix
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值