摘自http://blog.sina.com.cn/s/blog_6cc084c90100nf39.html

---------------------------------------------------------------------------------

一.利用ELFHash策略多线程抓取网页

这些天看了其它小组的博客,发现大家用Heritrix抓取所花的时间都比较长,基本都要花上数天的时间才能抓完,名副其实的爬虫…之所以这么慢,一个重要的原因是heritrix在抓取时一般只运行了一个线程。在网上查找原因,得知这是因为在默认的情况下,Heritrix使用HostnameQueueAssignmentPolicy来产生key值,而这个策略是用hostname作为key值的,因此一个域名下的所有链接都会被放到同一个线程中去。如果对Heritrix分配URI时的策略进行改进,利用ELF hash算法把url尽量平均分部到各个队列中去,就能够用较多的线程同时抓取一个域名下的网页,速度将得到大大的提高。

具体的做法如下:

1.在org.archive.crawler.frontier下新建一个ELFHashQueueAssignmentPolicy类,这个类要注意继承自 QueueAssignmentPolicy。

2.在该类下编写代码如下:

 public class ELFHashQueueAssignmentPolicy extends QueueAssignmentPolicy{
@Override
public String getClassKey(CrawlController controller, CandidateURI cauri) {
return this.ELFHash(cauri.getUURI().toString(), 50) + "";
} public int ELFHash(String str, int number) {
int hash = 0;
long x = 0l;
char[] array = str.toCharArray();
for (int i = 0; i < array.length; i++) {
hash = (hash << 4) + array[i];
if ((x = (hash & 0xF0000000L)) != 0) {
hash ^= (x >> 24);
hash &= ~x;
}
}
int result = (hash & 0x7FFFFFFF) % number;
return result;
}
}

3.  修改AbstractFrontier 类的AbstractFrontier方法 :

关键代码段是:

String queueStr = System.getProperty(AbstractFrontier.class.getName() +
                 "." + ATTR_QUEUE_ASSIGNMENT_POLICY,
                  ELFHashQueueAssignmentPolicy.class.getName() + " " +

HostnameQueueAssignmentPolicy.class.getName() + " " +

IPQueueAssignmentPolicy.class.getName() + " " +

BucketQueueAssignmentPolicy.class.getName() + " " +

SurtAuthorityQueueAssignmentPolicy.class.getName());

Pattern p = Pattern.compile("\\s*,\\s*|\\s+");

String [] queues = p.split(queueStr);

其中红色部分是新加的代码。

4.  修改heritrix.properties 中的配置

#############################################################################
        # F R O N T I E R                                                          
        #############################################################################

# List here all queue assignment policies you'd have show as a
        # queue-assignment-policy choice in AbstractFrontier derived Frontiers
        # (e.g. BdbFrontier).
        org.archive.crawler.frontier.AbstractFrontier.queue-assignment-policy = \

org.archive.crawler.frontier.ELFHashQueueAssignmentPolicy \

org.archive.crawler.frontier.HostnameQueueAssignmentPolicy \

org.archive.crawler.frontier.IPQueueAssignmentPolicy \

org.archive.crawler.frontier.BucketQueueAssignmentPolicy \

org.archive.crawler.frontier.SurtAuthorityQueueAssignmentPolicy \

org.archive.crawler.frontier.TopmostAssignedSurtQueueAssignmentPolicy

org.archive.crawler.frontier.BdbFrontier.level = INFO

红色部分为新加部分。

添加代码后运行的结果如下图,可见Heritrix已经在开50个线程同时抓取网页。

抓取速度得到了很大的提高,1.4G的网页8个多小时就抓好了。在Hosts栏里显示,只抓取了ccer.pku.edn.cn域名下的网页。

</:O:P>

一些分析:

1)添加的ELFHash算法程序并不算很复杂。ELFhash算法的基本思想是:将一个字符串的数组中的每个元素依次按前四位与上一个元素的低四位相与,组成一个长整形,如果长整的高四位大于零,那么就将它折回再与长整的低四位相异或,这样最后得到的长整对HASH表长取余,得到在HASH中的位置。

2)ELFHash函数将输入的字符串进行哈希计算,输出算出的整数型哈希值。getClassKey函数中调用了ELFHash函数计算出哈希值,转换为字符串型返回上一层。之所以取模100是因为一般情况下Heritrix开100个线程,对应100个不同的URI处理队列。

3)  QueueAssignmentPolicy类源程序里的说明:

* Establishes a mapping from CrawlURIs to String keys (queue names).

* Get the String key (name) of the queue to which the

* CrawlURI should be assigned.

*

* Note that changes to the CrawlURI, or its associated

* components (such as CrawlServer), may change its queue

* assignment.

可知该类建立抓取到的URI和抓取队列名之间的映射。这个类是个抽象类,不同的策略由不同的子类实现,如根据域名、IP等。

4)AbstractFrontier类是调度器基本实现类,是一个非常复杂的类,没有仔细研究。这里加在里面的程序作用大概是将ELFHashQueueAssignmentPolicy这个策略加入到运行时所使用的URI分配策略中。在heritrix.properties中的修改也同样为这个目的。

5)由上可见使用这个策略后,速度有了非常大的提高。但抓下来的1.4G数据相比之前抓下来的有点小,大概是max-retries值设置得太低(原来是30,改为5),导致不少东西没有抓下来。

二.只抓取HTML对象

由上面的图可以知道抓取的内容中有一些不需要用到的文件类型,比如pdf,jpeg等等。如何用Heritrix只抓特定的对象,比如只抓HTML型的。Heritrix的官方文档”Heritrix User Manual”中A.3节给出了一个解决方案:

1)You would first need to create a job with the single seed http://foo.org/bar/. You'll need to add the MirrorWriterProcessor on the Modules screen and delete the ARCWriterProcessor. This will store your files in a directory structure that matches the crawled URIs, and the files will be stored in the crawl job's mirror directory.

2)Your job should use the DecidingScope with the following set of DecideRules:

RejectDecideRule

SurtPrefixedDecideRule

TooManyHopsDecideRule

PathologicalPathDecideRule

TooManyPathSegmentsDecideRule

NotMatchesFilePatternDecideRule

PrerequisiteAcceptDecideRule

We are using the NotMatchesFilePatternDecideRule so we can eliminate crawling any URIs that don't end with .html. It's important that this DecideRule be placed immediately before PrerequisiteAcceptDecideRule; otherwise the DNS and robots.txt prerequisites will be rejected since they won't match the regexp.

3)On the Setting screen, you'll want to set the following for the NotMatchesFilePatternDecideRule:

decision: REJECT

use-preset-pattern: CUSTOM

regexp: .*(/|\.html)$

根据需要,将正则表达式进行修改以满足需要,在这里更改为:

(.*(/|\.(html|htm|xml|asp))$)|(.*\.asp\?.*)
    抓取的效果如下图所示:

三.取消Robots.txt的限制

Robots.txt是一种专门用于搜索引擎网络爬虫的文件,当构造一个网站时,如果作者希望该网站的内容被搜索引擎收录,就可以在网站中创建一个纯文本文件robots.txt,在这个文件中,声明该网站不想被robot访问的部分。这样,该网站的部分或全部内容就可以不被搜索引擎收录了,或者指定搜索引擎只收录指定的内容。因为大部分的网站并不会放置一个robots.txt文件以供搜索引擎读取,所以 Heritrix爬虫在抓取网页时会花费过多的时间去判断该Robots.txt文件是否存在,从而增加了抓取时间。好在这个协议本身是一种附加协议,完全可以不遵守。

在Heritrix中,对robots.txt文件的处理是处于PreconditionEnforcer这个Processor中的。PreconditionEnforcer是一个Prefetcher,当处理时,总是需要考虑一下当前这个链接是否有什么先决条件要先被满足的,而对robots.txt的访问则正好是其中之一。在PreconditionEnforcer中,有一个private类型的函数,函数声明为: private boolean considerRobotsPreconditions(CrawlURI curi)  。该函数的含义为:在进行对参数所表示的链接的抓取前,看一下是否存在一个由robots.txt所决定的先决条件。该函数返回true时的含义为需要考虑robots.txt文件,返回false时则表示不需要考虑robots.txt文件,可以继续将链接传递给后面的处理器。所以,最简单的修改办法就是将这个方法整个注释掉,只返回一个false值。

网上声称使用这种办法可以提高抓取速度一半以上,由于抓取所花时间比较多,没有进行对比比较。以上的抓取都是在去除robots.txt情况下进行的。

[转载]Heritrix 提高效率的若干方法的更多相关文章

  1. PhpStorm提高效率的使用方法及设置

    快捷键: CTRL + D  复制当前行到下一行 或 复制选中内容到选中内容之后 CTRL + Y  删除当前行或选中内容所涉及的行 CTRL + R  替换 CTRL + F  查找 ALT + 上 ...

  2. PhpStorm提高效率的使用方法及设置(快捷键)

    原文链接:https://my.oschina.net/chunto/blog/262954 快捷键: CTRL + D  复制当前行到下一行 或 复制选中内容到选中内容之后 CTRL + Y  删除 ...

  3. sql的简单提高效率方法

    少用in操作(效率极差),尽量用表关联代替 select要指定列,不要*(*会读入所有数据,而指定列则只提取涉及的列,减少io) 尽量有where(减少读取量),where操作列尽量有索引(加快查询) ...

  4. [转载]要提高SQL查询效率where语句条件的先后次序应如何写

    出处:https://www.cnblogs.com/exe19/p/5786806.html 我们要做到不但会写SQL,还要做到写出性能优良的SQL语句. (1)选择最有效率的表名顺序(只在基于规则 ...

  5. IT之快速提高效率的方法与思考

    前言 文章也没什么很高深的问题,大概花个5分钟能看完.是一些大家都知道的道理,作为提醒与总结. 关于提高方面的内容,一般都有个人的方法,但大致都一致.可分为几个步骤. 框架.工具使用相关 使用框架.工 ...

  6. Atitit.研发管理--提升效率--软件开发方法DSM总结o99

    Atitit.研发管理--提升效率--软件开发方法DSM总结o99 1. 什么是DSM? 1 2. DSM使用的语言DSL 2 3. 模型的优点 2 4. DSM 跟与MDA区别 2 5. MDA的实 ...

  7. 批处理文件(.bat)并行Arcpy脚本提高效率的思路

    Arcpy提供数据处理的方便接口,但一个Arcpy脚本通常只运行于一个核上.现在电脑通常是多核乃至多处理器,如果能将任务分解为可同时进行的若干任务,便可通过并行充分利用电脑性能. 折腾了python并 ...

  8. Oracle多表连接,提高效率,性能优化 (转)

    执行路径:ORACLE的这个功能大大地提高了SQL的执行性能并节省了内存的使用:我们发现,单表数据的统计比多表统计的速度完全是两个概念.单表统计可能只要0.02秒,但是2张表联合统计就可能要几十表了. ...

  9. SQL Server 百万级数据提高查询速度的方法

    1.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描. 2.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉 ...

随机推荐

  1. vs2015 不支持javascript的智能提示高亮

    有些人安装了vs2015后发现居然不支持javascrpt的高亮功能,连工具-选项-文本编辑器里面的javascript也没有了,楼主也碰到这么个情况了,估计是有与装了多个版本的原因,楼主电脑安装了V ...

  2. 修改EBS R12 URL连接端口

    (TEST环境8002端口)1.停止所有应用服务2.修改<SID>_<server>.xml配置文件(如test_vis.xml)cd $APPL_TOP/admin (如cd ...

  3. C#开发者通用性代码审查清单

    这是为C#开发者准备的通用性代码审查清单,可以当做开发过程中的参考.这是为了确保在编码过程中,大部分通用编码指导原则都能注意到.对于新手和缺乏经验(0到3年工作经验)的开发者,参考这份清单编码会很帮助 ...

  4. 修改host文件的P处理

    notepad C:\WINDOWS\system32\drivers\etc\hosts 用文档创建hosts文件,添加上面代码.把文件后缀修改为 .bat 就不用每次很麻烦的查找host文件了.

  5. struts2笔记05-ServletActionContext

    1.ServletActionContext ServletActionContext, 这个类继承自ActionContext, 所以它具有ActionContext的很多功能,不过更重要的是它提供 ...

  6. 关于ODI agent的配置部署

    分类: Linux 最近,做了几个ODI项目的部署,发现ODI agent所在的位置对整个E-LT工作的影响还是比较大的,根据Oracle的官方说法,agent一般需要部署在目标端的数据库服务器上,或 ...

  7. tail -f

    http://stackoverflow.com/questions/187587/looking-for-a-windows-equivalent-of-the-unix-tail-command ...

  8. 如何在 静态编译的QT 5.5.1 中 使用数据库插件连接 ODBC(调用静态插件)

    前段时间由于工作的关系,需要编写一个将数据插入到 Sql server 2012 的桌面软件. 由于之前使用的是MFC,偶然间接触到了Qt后,被它的简洁惊艳到了,于是便毅然而然的转投到了Qt的怀抱,哈 ...

  9. Unix/Linux环境C编程入门教程(17) Gentoo LinuxCCPP开发环境搭建

    1. Gentoo Linux是一套通用的.快捷的.完全免费的Linux发行,它面向开发人员和网络职业人员.与其他发行不同的是,Gentoo Linux拥有一套先进的包管理系统叫作Portage.在B ...

  10. 简单实现计算Edit Distance算法

    最近因为工作需要,学习了NLP的相关知识,简单动手实现了一下计算Edit Distance的算法,就是计算一个字符串要变成另一个字符串需要的代价,这其中采用Levenshtein方式,即规定一个插入和 ...