摘要:从BdbFrontier对象的next方法(从某个Classkey标识的BdbWorkQueue工作队列)取出来的CrawlURI uri对象第一步要进入的处理器是Preselector处理器,该处理器主要是对CrawlURI uri对象根据配置文件里面配置的正则表达式进行过滤,通过过滤的Crawl...
阅读全文
04 2013 档案
摘要:作为CrawlURI uri对象在处理器链中的生命周期,本人认为逻辑上应该从FrontierPreparer处理器开始,再经过后续的处理器(其实具体CrawlURI uri对象的生命周期,是在它的父级CrawlURI uri对象的抽取处理器处理时已经初具雏形,父级CrawlURI uri对象与它的子级CrawlURI uri对象的生命周期是交错的,关于处理器的流程我在前面已经描述过)经过FrontierPreparer处理器处理的CrawlURI uri对象下一步才是进入BdbFrontier对象的Schedule方法添加到BdbWorkQueue工作队列该处理器主要是为CrawlURI ur
阅读全文
摘要:本文接下来分析CrawlServer类和CrawlHost类,两者都实现了IdentityCacheable接口(可缓存对象接口)CrawlServer对象代表服务器,里面存储了服务器的相关信息,包括服务名 端口 robots信息 Credential集合及相关操作等private static final long serialVersionUID = 3L; public static final long ROBOTS_NOT_FETCHED = -1; /** only check if robots-fetch is perhaps superfluous * ...
阅读全文
摘要:Heritrix3.1.0系统里面的组件以及对象之间总是存在千丝万缕的联系,本人为了表述某个功能的具体实现总是不得不牵涉到相关的对象及其实现,不然本人无法将该功能实现的逻辑描述清楚;可是在逻辑上本人又不得不考虑到话题的连贯性,本人姑妄言之,读者姑妄听之本文接下来要分析的是ServerCache类及CrawlHost和CrawlServer类,了解这些类的作用是继续分析的前提ServerCache是抽象类,在全局上为Heritrix3.1.0系统应用提供CrawlHost对象和CrawlServer对象的注册/** * Abstract class for crawl-global regist
阅读全文
摘要:上文分析了Heritrix3.1.0系统的对请求认证机制的封装,本文接下来分析Heritrix3.1.0系统对cookies的处理的封装Heritrix3.1.0系统提供了CookieStorage接口,用于提供cookies的存储CookieStorage接口很简单,声明了保存cookies对象的Map容器的方法和获取cookies对象的Map容器的方法public interface CookieStorage extends Lifecycle { SortedMap<String,Cookie> getCookiesMap(); void saveCookiesMap(Ma
阅读全文
摘要:上文分析了Heritrix3.1.0系统对HttpClient组件的请求处理类的封装,本文接下来分析Heritrix3.1.0系统是怎样封装请求证书的Heritrix3.1.0系统的package org.archive.modules.credential里面的相关类都是与请求证书有关的先来了解一下CredentialStore类,该类用Map类型存储了应用的所有证书(Credential),外部只要调用这个类就可以获取证书该类重要方法如下KeyedProperties kp = new KeyedProperties(); public KeyedProperties getKeye...
阅读全文
摘要:Heritrix 3.1.0 源码解析(二十三)中我们分析了Heritrix3.1.0系统是怎样扩展HttpClient组件的HttpConnection连接对象和相应的管理接口HttpConnectionManagerHttpConnection连接对象里面创建了SOCKET连接,但是还没用向输出流写数据,也没有从输入流读数据, 这里面HttpClient组件是怎么实现的,Heritrix3.1.0系统又是怎么扩展的呢?我们知道,当我们用HttpClient组件执行网页请求时,根据我们要请求的网页是GET请求还是POST请求我们创建相应的GetMethod类或PostMethod类(当然还有
阅读全文
摘要:上文中我们提到Recorder httpRecorder = Recorder.getHttpRecorder()对象封装了SOCKET连接的输出流和输入流,我们下面来看看Recorder类是怎么封装SOCKET的输入流和输出流的Recorder类的重要成员如下,主要包括封装的输入流和输出流以及有序的字符序列(缓存到本地文件) private RecordingInputStream ris = null; private RecordingOutputStream ros = null; /** * Backing file basename. * ...
阅读全文
摘要:上文分析了Heritrix3.1.0系统是怎么扩展HttpClient组件的ProtocolSocketFactory接口用于创建HTTP和HTTPS连接的SOCKET对象的接下来我们分析Heritrix3.1.0系统是怎么扩展HttpClient组件的HttpConnection对象的(创建SOCKET连接)先看一下HttpConnection类的成员变量// ----------------------------------------------------- Instance Variables /** My host. */ private String hos...
阅读全文
摘要:本文继续分析Heritrix3.1.0系统的源码,其实本人感觉接下来待分析的问题不是一两篇文章能够澄清,本人不能因为迫于表述而乱了问题本身的章法,接下来的分析的Heritrix3.1.0系统封装HttpClient组件可能要分几篇文章来解析我们知道,Heritrix3.1.0系统是通过封装HttpClient组件(里面封装了Socket)来与服务器通信的,Socket的输出流写入数据,输入流接收数据那么Heritrix3.1.0系统是怎样封装Httpclient(Heritrix3.1.0系统是采用的以前的Apache版本)组件的呢?我们可以看到,在FetchHTTP处理器里面有一段静态代码块
阅读全文
摘要:上文中的抽象类Scoper关联到另外一个成员变量DecideRule scope,我不得不先中断处理器类的分析(后面再继续处理器分析),来插叙一下DecideRule scope对象,我说了,DecideRule scope成员是用来控制CrawlURI caUri对象的范围照例先来浏览一下DecideRule相关类图DecideRule类是一个抽象类,用来判断一个CrawlURI caUri对象是接受还是拒绝public DecideResult decisionFor(CrawlURI uri) { if (!getEnabled()) { return...
阅读全文
摘要:本文接着上文分析,CandidateChain candidateChain处理器链相关联的处理器CandidateChain处理器链有两个处理器org.archive.crawler.prefetch.CandidateScoperorg.archive.crawler.prefetch.FrontierPreparer要了解上面的处理器,我们先要了解另外一个抽象类Scoper,继承自抽象父类Processor,该类用来控制CrawlURI caUri对象的范围,里面有一个成员变量DecideRule scope protected DecideRule scope; public D...
阅读全文
摘要:本文继续分析与heritrix3.1.0系统的处理器相关的源码我们照例先来浏览一下class uml图所有的处理器都继承自抽象父类Processor,其中重要的方法如下/** * Processes the given URI. First checks {@link #ENABLED} and * {@link #DECIDE_RULES}. If ENABLED is false, then nothing happens. * If the DECIDE_RULES indicate REJECT, then the * {@link #innerR...
阅读全文
摘要:从本文开始,我们来分析与Heritrix3.1.0系统的处理器相关的源码,在Heritrix系统里面,待处理的CrawlURI cURI对象经过系统里面的处理器的重重处理最后才得以修成正果因为处理器很多,除了处理器本身的继承层次的逻辑外,在系统里面将功能相近的处理器归入同一个处理器链Heritrix3.1.0系统逻辑上抽象为两大处理器链(FetchChain和DispositionChain,CandidateChain逻辑上是属于DispositionChain)我们先来看一下处理器链与处理器的相关UML图上面是静态class图,处理器链ProcessorChain维持着一定数目的处理器pr
阅读全文
摘要:我们接下来分析与与BdbFrontier对象void finished(CrawlURI cURI)方法相关的方法/** * Note that the previously emitted CrawlURI has completed * its processing (for now). * * The CrawlURI may be scheduled to retry, if appropriate, * and other related URIs may become eligible for release * via the ne...
阅读全文
摘要:我们接下来分析与与BdbFrontier对象CrawlURI next()方法相关的方法/** * Return the next CrawlURI eligible to be processed (and presumably * visited/fetched) by a a worker thread. * * Relies on the readyClassQueues having been loaded with * any work queues that are eligible to provide a URI. * ...
阅读全文
摘要:本文分析Heritrix3.1.0系统里面的WorkQueue队列(具体是BdbWorkQueue)的调度机制,这部分是系统里面比较复杂的,我只能是尝试分析(本文可能会修改)我在Heritrix 3.1.0 源码解析(六)一文中涉及BdbFrontier对象的初始化,现在回顾一下我们看到在WorkQueueFrontier类中的初始化方法void start()里面进一步调用了void initInternalQueues()方法而void initInternalQueues()方法 里面进一步调用子类BdbFrontier的void initOtherQueues()方法与void ini
阅读全文
摘要:我在分析BdbFrontier对象的void schedule(CrawlURI caURI)、CrawlURI next() 、void finished(CrawlURI cURI)方法是,其实还有一些相关环境没有分析,其实我是有点疲倦本文接下来分析在多线程环境中Heritrix3.1.0系统怎样保持相关对象属性的一致性以及怎样自定义配置相关对象的属性值我们在WorkQueueFrontier类的void schedule(CrawlURI curi)方法里面可以看到@Override public void schedule(CrawlURI curi) { shee...
阅读全文
摘要:接下来分析BdbFrontier类的void finished(CrawlURI curi) 方法,完成CrawlURI对象的扫尾工作在BdbFrontier类的父类的父类AbstractFrontier里面org.archive.crawler.frontier.BdbFrontier org.archive.crawler.frontier.AbstractFrontier/** * Note that the previously emitted CrawlURI has completed * its processing (for now). * ...
阅读全文
摘要:接下来分析BdbFrontier类的CrawlURI next()方法,该方法是获取下一个待采集的CrawlURI对象该方法是在BdbFrontier类的父类的父类AbstractFrontier里面org.archive.crawler.frontier.BdbFrontier org.archive.crawler.frontier.AbstractFrontier/* (non-Javadoc) * @see org.archive.crawler.framework.Frontier#next() */ public CrawlURI next() thr...
阅读全文
摘要:上文分析了Heritrix3.1.0系统是怎么添加CrawlURI curi对象的,那么在系统初始化的时候,是怎么载入CrawlURI curi种子的呢?我们回顾前面的文章,在我们执行采集任务的launch指令的时候,实际会调用CrawlController对象的void requestCrawlStart()方法/** * Operator requested crawl begin */ public void requestCrawlStart() { hasStarted = true; sendCrawlStateChangeEv...
阅读全文
摘要:本文要分析的是Heritrix3.1.0的Frontier组件,先熟悉一下相关的UML类图通过浏览该图,我们可以清楚的看出Frontier组件的相关接口和类的继承和调用关系,不必我再文字描述了在分析BdbFrontier类的相关方法之前,有必要熟悉一下在系统环境中该对象的初始状态,以及状态的改变这部分内容需要回顾Heritrix 3.1.0 源码解析(六)一文,本人就不在这里重复了BdbFrontier类重要的有几个方法,分别是添加CrawlURI,获取CrawlURI,完成CrawlURIvoid schedule(CrawlURI curi)CrawlURI next()void fini
阅读全文
摘要:Heritrix3.1.0系统里面Frontier组件管理链接队列,采用的是BDB数据库,利用BDB数据库来存储CrawlURI对象,首先我们来看Heritrix3.1.0是怎么实现BDB模块的我们知道,创建BDB数据库首先要构建数据库环境,Heritrix3.1.0的BDB模块里面EnhancedEnvironment类实现了对BDB数据库环境的封装(继承自je的Environment),如果你不熟悉BDB数据库,可以先google一下吧EnhancedEnvironment类的源码如下:/** * Version of BDB_JE Environment with additional
阅读全文
摘要:本文接着分析存储CrawlURI curi的队列容器,最重要的是BdbWorkQueue类及BdbMultipleWorkQueues类BdbWorkQueue类继承自抽象类WorkQueue,抽象类WorkQueue最重要的方法是long enqueue(final WorkQueueFrontier frontier,CrawlURI curi)CrawlURI peek(final WorkQueueFrontier frontier)void dequeue(final WorkQueueFrontier frontier, CrawlURI expected)分别为添加CrawlUR
阅读全文
摘要:本文接下来分析上文涉及到的ObjectIdentityCache接口及相关对象先熟悉一下继承和依赖关系,简要UML类图如下:我们先来了解一下ObjectIdentityCache接口的源码(泛型接口)/** * An object cache for create-once-by-name-and-then-reuse objects. * * Objects are added, but never removed. Subsequent get()s using the * same key will return the exact same object, UNLESS all ...
阅读全文
摘要:本文分析BdbFrontier对象的相关状态和方法BdbFrontier类继承自WorkQueueFrontier类 WorkQueueFrontier类继承自AbstractFrontier类BdbFrontier类的void start()方法如下(在其父类WorkQueueFrontier里面):org.archive.crawler.frontier.BdbFrontier org.archive.crawler.frontier.WorkQueueFrontierpublic void start() { if(isRunning()) { ...
阅读全文
摘要:我们从上文的CrawlController对象可以看到,爬虫任务是通过ToePool类建立线程ToeThread的线程池的我们在了解采集线程池的相关类之前,先有必要了解一下CrawlController类,因为我们的爬虫操作指令最终是通过调用CrawlController对象的方法的CrawlController类的成员和方法都是直接与采集任务相关的,好比控制中心// ApplicationContextAware implementation, for eventing AbstractApplicationContext appCtx; public void setAppli...
阅读全文
摘要:如果孤立的发现某类的方法,不免使我们难以理解它的含义;当我们将对象的相互作用串起来的时候,更容易理解方法的意图在对象之间相互通信时,首先应该了解对象的状态;最基本的入手方式就是 了解它的构造函数或者初始化方法以及执行相关方法后状态的变化,其次是相应方法的输入参数(发送消息)当我们在后台建立一个爬行任务时,在Heritrix3.1.0系统里面对应一个爬行任务类,当前爬行任务的所有属性和行为都封装在这个爬行任务类里面这个类为CrawlJob(org.archive.crawler.framework),我们先来熟悉一下该类的相关成员和方法爬行任务CrawlJob类实现了两接口Comparable&
阅读全文
摘要:如果从heritrix3.1.0系统的静态逻辑结构入手,往往看不到系统相关对象的交互作用;如果只从系统的对象动态结构 分析,则又看不到系统的逻辑轮廓所以源码分析需要动静兼顾,使我们更容易理解它的逻辑与交互,本文采用这个分析方法入手本文要分析的是spring给Heritrix3.1.0系统bean带来了什么样的管理方式,spring容器的配置文件我们已从上文有了初步的了解先了解spring容器在系统中是怎样加载配置文件以及怎么初始化的,当我们执行采集任务的build操作时调用CrawlJob对象的void validateConfiguration()/** * Does the ass...
阅读全文
摘要:上文Heritrix 3.1.0 源码解析(一)实际上是讲述Heritrix3.1.0在eclipse中的环境搭建,还属于对Heritrix3.1.0 源码解析的热身阶段,本文接着分析Heritrix 3.1.0的任务配置,Heritrix3.1.0版本与原来的Heritrix1.14.4版本很大的不同是 任务配置文件从order.xml文件转到了crawler-beans.cxml文件,而crawler-beans.cxml实际上是一个spring的容器配置文件,是用spring管理的,我们先来眼熟一下该文件的样子(这里面我配置了一个任务): # This Propertie...
阅读全文
摘要:Heritrix是一个比较经典的开源爬虫,本人打算用它来做一些数据采集应用网上关于heritrix系列的博文 大多是老版本的(1.14.4版本),Heritrix 3.1.0版本的文章则极其稀少由于新的版本相对老版本改动比较大,所以本人不能循老版本的套路了(Heritrix 3.1.0 版本引入spring容器管理,相对增强了对spring熟悉的开发人员的亲和性)首先介绍新的Heritrix 3.1.0 版本怎么在eclipse下搭建环境,以便于自己调试与开发网上介绍在Eclipse中搭建Heritrix 3.1.0的文章总是讲的很复杂,无疑增加了开发人员对它的敬畏感,不利于Heritrix
阅读全文
摘要:上文最后提到jackrabbit的检索默认实现类QueryImpl,先熟悉一下该类的继承层次QueryImpl继承自抽象类AbstractQueryImpl,而抽象类实现了Query接口(JCR的接口)Query接口源码如下:/** * A Query object. */public interf...
阅读全文
摘要:本文家下来分析SearchManager类的源码,该类实现了SynchronousEventListener接口,而SynchronousEventListener接口继承自EventListener接口,EventListener接口只有一个事件监听方法SearchManager类的源码如下:/*...
阅读全文
摘要:本文接着分析jackrabbit与lucene交互的核心类SearchIndex,lucene的索引与检索都是通过该类实现的SearchIndex类继承自抽象类AbstractQueryHandler,而抽象类AbstractQueryHandler实现了QueryHandler接口先浏览一下Que...
阅读全文
摘要:上文分析了jackrabbit对富文档的文本抽取实现的源码,我们注意到,上文的文本抽取类LazyTextExtractorField继承自lucene的AbstractField类,即LazyTextExtractorField类是Field类型的,这正是构建lucene索引Document里面的F...
阅读全文
摘要:几年前某位大牛写了 深入浅出 jackrabbit系列,链接地址为http://ahuaxuan.iteye.com/category/65829本人读后受益匪浅(如果没用他的辅助之功,本人对jackrabbit的理解可能会摸索得更长),由于时隔久远,当时的jackrabbit版本为1.7,与现在的...
阅读全文
摘要:1、用户自定义的类加载器:要创建用户自己的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的findClass(String name)方法即可,该方法根据参数指定类的名字,返回对应的Class对象的引用。findClassprotected Class<?> findClass(String name) throws ClassNotFoundException使用指定的二进制名称查找类。此方法应该被类加载器的实现重写,该实现按照委托模型来加载类。在通过父类加载器检查所请求的类后,此方法将被 loadClass 方法调用。...
阅读全文
摘要:简介:jspf(JavaSimplePluginFramework)是一个插件框架,用于减少小型项目的的开发时间,增加代码的可维护性。他完全隐藏了组件的详细实现,只用到他们的接口。加载组件所需要的代码也很少,便于编写。jspf框架完全基于java注释实现@PluginImplementation,@InjectPlugin,@PluginLoaded,@Timer和@Thread等.(关于java注释:元数据从metadata一词译来,就是“关于数据的数据”的意思。越来越的开源框架都提供了“元数据”支持,其实也就是注释支持。Annotation是从java5开始在语言级别提供的一项新特性,An
阅读全文