- 浏览: 1184006 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (350)
- Ajax研究 (2)
- javascript (22)
- struts (15)
- hibernate (12)
- spring (8)
- 我的生活 (28)
- jsp (2)
- 我的随笔 (84)
- 脑筋急转弯 (1)
- struts2 (2)
- ibatis (1)
- groovy (1)
- json (4)
- flex (20)
- Html Css (5)
- lucene (11)
- solr研究 (2)
- nutch (25)
- ExtJs (3)
- linux (6)
- 正则表达式 (2)
- xml (1)
- jetty (0)
- 多线程 (1)
- hadoop (40)
- mapreduce (5)
- webservice (2)
- 云计算 (8)
- 创业计划 (1)
- android (8)
- jvm内存研究 (1)
- 新闻 (2)
- JPA (1)
- 搜索技术研究 (2)
- perl (1)
- awk (1)
- hive (7)
- jvm (1)
最新评论
-
pandaball:
支持一下,心如大海
做有气质的男人 -
recall992:
山东分公司的风格[color=brown]岁的法国电视[/co ...
solr是如何存储索引的 -
zhangsasa:
-services "services-config ...
flex中endpoint的作用是什么? -
来利强:
非常感谢
java使用json所需要的几个包 -
zhanglian520:
有参考价值。
hadoop部署错误之一:java.lang.IllegalArgumentException: Wrong FS
当我们以Web UI方式使用Heritrix时,点击任务开始(start)按钮时,Heritrix就开始了它的爬取工作.但它的内部
执行流程是怎样的呢?别急,下面将慢慢道来.
(一)CrawlJobHandler
当点击任务开始(start)按钮时,将执行它的startCrawler()方法:
if(sAction.equalsIgnoreCase("start"))
{
// Tell handler to start crawl job
handler.startCrawler();
}
再来看看startCrawler()方法的执行:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->public class CrawlJobHandler implements CrawlStatusListener {
public void startCrawler() {
running = true;
if (pendingCrawlJobs.size() > 0 && isCrawling() == false) {
// Ok, can just start the next job
startNextJob();
}
}
protected final void startNextJob() {
synchronized (this) {
if(startingNextJob != null) {
try {
startingNextJob.join();
} catch (InterruptedException e) {
e.printStackTrace();
return;
}
}
startingNextJob = new Thread(new Runnable() {
public void run() {
startNextJobInternal();
}
}, "StartNextJob");
//当前任务线程开始执行
startingNextJob.start();
}
}
protected void startNextJobInternal() {
if (pendingCrawlJobs.size() == 0 || isCrawling()) {
// No job ready or already crawling.
return;
}
//从待处理的任务列表取出一个任务
this.currentJob = (CrawlJob)pendingCrawlJobs.first();
assert pendingCrawlJobs.contains(currentJob) :
"pendingCrawlJobs is in an illegal state";
//从待处理列表中删除
pendingCrawlJobs.remove(currentJob);
try {
this.currentJob.setupForCrawlStart();
// This is ugly but needed so I can clear the currentJob
// reference in the crawlEnding and update the list of completed
// jobs. Also, crawlEnded can startup next job.
this.currentJob.getController().addCrawlStatusListener(this);
// now, actually start
//控制器真正开始执行的地方
this.currentJob.getController().requestCrawlStart();
} catch (InitializationException e) {
loadJob(getStateJobFile(this.currentJob.getDirectory()));
this.currentJob = null;
startNextJobInternal(); // Load the next job if there is one.
}
}
}
由以上代码不难发现整个流程如下:
可以看出,最终将启动CrawlController的requestCrawlStart()方法.
(二)CrawlController
该类是一次抓取任务中的核心组件。它将决定整个抓取任务的开始和结束.
先看看它的源代码:在构造 CrawlController实例,需要先做以下工作:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->package org.archive.crawler.framework;
public class CrawlController implements Serializable, Reporter {
// key subcomponents which define and implement a crawl in progress
private transient CrawlOrder order;
private transient CrawlScope scope;
private transient ProcessorChainList processorChains;
private transient Frontier frontier;
private transient ToePool toePool;
private transient ServerCache serverCache;
// This gets passed into the initialize method.
private transient SettingsHandler settingsHandler;
}
CrawlOrder:它保存了对该次抓取任务中order.xml的属性配置。
CrawlScope:决定当前抓取范围的一个组件。
ProcessorChainList:从名称上可知,其表示处理器链。
Frontier:它是一个URL的处理器,决定下一个要被处理的URL是什么。
ToePool:它表示一个线程池,管理了所有该抓取任务所创建的子线程。
ServerCache:它表示一个缓冲池,保存了所有在当前任务中,抓取过的Host名称和Server名称。
(1)首先构造一个XMLSettingsHandler对象,将order.xml内的属性信息装入,并调用它的initialize方法进行初始化。
(2)调用CrawlController构造函数,构造一个CrawlController实例
(3)调用CrawlController的initilize(SettingsHandler)方法,初始化CrawlController实例。其中,传入的参数就是
在第一步里构造的XMLSettingsHandler实例。
(4 )当上述3步完成后,CrawlController就具备了运行的条件。此时,只需调用它的requestCrawlStart()方法,就
可以启动线程池和Frontier,然后开始不断的抓取网页。
先来看看initilize(SettingsHandler)方法:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->public void initialize(SettingsHandler sH)
throws InitializationException {
sendCrawlStateChangeEvent(PREPARING, CrawlJob.STATUS_PREPARING);
this.singleThreadLock = new ReentrantLock();
this.settingsHandler = sH;
//从XMLSettingsHandler中取出Order
this.order = settingsHandler.getOrder();
this.order.setController(this);
this.bigmaps = new Hashtable<String,CachedBdbMap<?,?>>();
sExit = "";
this.manifest = new StringBuffer();
String onFailMessage = "";
try {
onFailMessage = "You must set the User-Agent and From HTTP" +
" header values to acceptable strings. \n" +
" User-Agent: [software-name](+[info-url])[misc]\n" +
" From: [email-address]\n";
//检查了用户设定的UserAgent等信息,看是否符合格式
order.checkUserAgentAndFrom();
onFailMessage = "Unable to setup disk";
if (disk == null) {
setupDisk(); //设定了开始抓取后保存文件信息的目录结构
}
onFailMessage = "Unable to create log file(s)";
//初始化了日志信息的记录工具
setupLogs();
onFailMessage = "Unable to test/run checkpoint recover";
this.checkpointRecover = getCheckpointRecover();
if (this.checkpointRecover == null) {
this.checkpointer =
new Checkpointer(this, this.checkpointsDisk);
} else {
setupCheckpointRecover();
}
onFailMessage = "Unable to setup bdb environment.";
//初始化使用Berkley DB的一些工具
setupBdb();
onFailMessage = "Unable to setup statistics";
setupStatTracking();
onFailMessage = "Unable to setup crawl modules";
//初始化了Scope、Frontier以及ProcessorChain
setupCrawlModules();
} catch (Exception e) {
String tmp = "On crawl: "
+ settingsHandler.getSettingsObject(null).getName() + " " +
onFailMessage;
LOGGER.log(Level.SEVERE, tmp, e);
throw new InitializationException(tmp, e);
}
Lookup.getDefaultCache(DClass.IN).setMaxEntries(1);
//dns.getRecords("localhost", Type.A, DClass.IN);
//实例化线程池
setupToePool();
setThresholds();
reserveMemory = new LinkedList<char[]>();
for(int i = 1; i < RESERVE_BLOCKS; i++) {
reserveMemory.add(new char[RESERVE_BLOCK_SIZE]);
}
}
可以看出在initilize()方法中主要做一些初始化工作,但这些对于Heritrix的运行是必需的.
再来看看CrawlController的核心,requestCrawlStart()方法:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> public void requestCrawlStart() {
//初始化处理器链
runProcessorInitialTasks();
sendCrawlStateChangeEvent(STARTED, CrawlJob.STATUS_PENDING);
String jobState;
state = RUNNING;
jobState = CrawlJob.STATUS_RUNNING;
sendCrawlStateChangeEvent(this.state, jobState);
// A proper exit will change this value.
this.sExit = CrawlJob.STATUS_FINISHED_ABNORMAL;
Thread statLogger = new Thread(statistics);
statLogger.setName("StatLogger");
//开始日志线程
statLogger.start();
//启运Frontier,抓取工作开始
frontier.start();
}
可以看出,做了那么多工作,最终将启动Frontier的start方法,而Frontier将为线程池的线程提供URI,真正开始
抓取任务.至此,抓取任务开始.
发表评论
-
认真阅读hadoop源码
2012-11-01 16:00 1782从新复习hadoop,认真阅读hadoop源码,有兴趣的朋友可 ... -
铁道部售票网站怎么啦?
2012-01-10 10:25 1880乐淘CTO李勇:库存同步是难点 我的判断,除了 ... -
eclipse启动报错jvm terminated. Exit code=1
2011-10-11 08:55 1225转载链接: http://wxmfly.itey ... -
ireport中获取当前时间
2011-08-28 11:53 5172一。 iReport 中获取系统当前时间 1,选择Tex ... -
ireport引java bean database
2011-08-27 10:38 1748今天帮一同事调试程序,他们的报表工具用的是ireport4.0 ... -
谈谈爬虫的设计
2011-08-07 22:27 2321网络蜘蛛现在开源的已 ... -
为了养家,只能这样!
2011-07-03 16:22 16还是一直在玩数据,hadoop平台(自己一手搭建),使用爬虫n ... -
陆续整理数据方面的资料
2011-05-07 08:58 635差不多有一个多月没写东西了,最近比较忙!还是研究数据一些东西。 ... -
挣钱养家
2011-04-14 22:19 1163如果各位有私活的话忙不过来,可以通过QQ(282215036) ... -
使用perl连接mysql数据库
2011-04-05 22:21 1440用Perl DBI连接MySQL数据库 Perl中一个最酷的 ... -
图像数字识别技术
2011-04-01 17:32 5942最近在研究图像数字识别技术,对于一些简单没有干扰的图片,可以读 ... -
100个可供选择的搜索引擎
2011-03-02 13:11 1511本文根据 readwriteweb ... -
对于处理问题的一点想法
2011-02-23 08:26 1123昨天快下班的时候,遇到一个建立索引的问题,因为快下班了,我没有 ... -
温故而知新
2011-02-20 16:44 1190又回过头来复习以前的知识了?在家里实在无聊!把之前学习过的东西 ... -
加钱也得买票回家过年
2011-01-25 08:44 984昨天从黄牛党手上拿了一张高价票。加了100.哎!这年头在外面忙 ... -
Eclipse3.6 Helios SVN插件–Subversive
2011-01-12 11:42 3655刚在Google Code上发布了一个Open Project ... -
博客有时候来不及更新,希望大家见谅!
2011-01-10 17:42 1012刚到新公司,可能开始忙了,博客有时候来不及更新,希望大家见谅! ... -
新公司入职第一天
2011-01-10 11:47 1330今天是我去新公司入职的第一天。感觉一切都是新的,从头开始!加油 ... -
java中各种算法的实现
2010-12-30 13:01 1165选择排序算法的JAVA实现 viewplainprin ... -
java基础知识复习
2010-12-30 13:00 1021学习Java一 配置环境变量 学习Java二 开发第一 ...
相关推荐
- `CrawlController`管理多个爬虫实例,支持多线程爬取。 - `UrlQueue`和`Url Frontier`类实现了URL的存储和调度策略。 **4. 依赖包的作用:** - 除了Crawler4j自身的类包外,还可能包含如Apache HttpClient或...
CrawlController controller = new CrawlController(config); controller.addSeed("http://example.com"); controller.start(MyCrawler.class, 5); // 5个并发线程 ``` 以上就是关于crawler4j-4.1-jar-with-...
7. **数据处理和分析**:在抓取过程中,Heritrix可以对网页内容进行预处理和提取,这包括解析HTML,提取文本,去除无用信息,以及对链接进行调度和优先级排序。这些处理对于构建搜索引擎至关重要,因为它允许对抓取...
通过集成其他的解析器和解析库,如Apache Tika或Boilerpipe,Heritrix可以更好地解析和提取网页内容。 总的来说,Heritrix是一个功能强大的网络爬虫工具,不仅适用于数据挖掘、研究项目,也适合那些需要大规模网络...
在实际使用中,开发者通常会根据项目需求,自定义各种组件,例如种子列表(定义初始抓取的URL)、过滤器(控制哪些内容被抓取和忽略)、解析器(解析HTML或其他文档格式)和存储模块(决定如何保存抓取的数据,如...
处理器链包括PreProcessor、Fetcher、Extractor、Writer和PostProcessor五个队列,分别处理抓取的先决条件、网络传输协议、内容解析、信息写入和后期处理。 总结来说,搜索引擎系统中的网页抓取模块是关键,它决定...
它由多个模块组成,如调度器(Scheduler)、处理器(Processor)、过滤器(Filter)、存档器(Archiver)等,每个组件都有特定的任务,如决定何时抓取网页、如何解析内容、如何存储结果等。用户可以根据需求扩展或...
本文将深入解析Heritrix的架构及其增量抓取的实现策略。 Heritrix的架构主要包括以下几个核心组件: 1. **Web Administrative Console**:这是一个基于Web的控制台,方便用户远程管理和监控爬虫任务。Heritrix内建...
在“扩增需要注意的地方”中,文档提醒读者在实现自定义内容提取器时要注意Heritrix3的一些内部机制,如org.archive.crawler.framework.CrawlController中的fetchChain对象。这一对象是执行抓取流程的核心,用户在...
11. `org.archive.crawler.framework`:Heritrix的框架包,定义了核心类如CrawlController(爬虫控制器)和Frontier(调度器),是整个系统架构的基础。 12. `org.archive.crawler.framework.exceptions`:框架异常...