原创作者: pengranxiang   阅读:2980次   评论:0条   更新时间:2011-05-26    
本节解析与处理器有关的内容.

与处理器有关的主要在以下几个类:Processor(处理器类),ProcessorChain(处理器类),ProcessorChainList(处理器链列表).它们之间的关系如下:

下面将解析该图.

(1)Processor

代表一个处理器.

 


<!---->package org.archive.crawler.framework;

public class Processor extends ModuleType {
//默认的下一个处理器
    private Processor defaultNextProcessor = null;
 
/**
     * Perform processing on the given CrawlURI.
     *    处理一个链接
     * 
@param curi
     * 
@throws InterruptedException
     
*/
    
public final void process(CrawlURI curi) throws InterruptedException {
        
// by default, arrange for curi to proceed to next processor
        
//设置当前处理器的下一个处理器
        curi.setNextProcessor(getDefaultNextProcessor(curi));

        
// Check if this processor is enabled before processing
        try {
            
if (!((Boolean) getAttribute(ATTR_ENABLED, curi)).booleanValue()) {
                
return;
            }
        } 
catch (AttributeNotFoundException e) {
            logger.severe(e.getMessage());
        }

        
if(rulesAccept(curi)) {
            innerProcess(curi); 
//留给子类实现
        } else {
            innerRejectProcess(curi);
        }
    }

 

 

 

(2)ProcessorChain

该类实际上实现一个队列的功能,它代表一个由许多处理器连接的处理器链.

 


<!---->package org.archive.crawler.framework;
public class ProcessorChain {
 
//存放当前处理链中所有的处理器
    private final MapType processorMap;
    
//下一个处理器链
    private ProcessorChain nextChain;
    
//处理器链的第一个处理器
    private Processor firstProcessor;
/** Construct a new processor chain.
     *    把该处理链的所有的处理器连接起来
     * 
@param processorMap a map of the processors belonging to this chain.
     
*/
    
public ProcessorChain(MapType processorMap) {
        
this.processorMap = processorMap;

        Processor previous 
= null;

        
for (Iterator it = processorMap.iterator(null); it.hasNext();) {
            Processor p 
= (Processor) it.next();

            
if (previous == null) {
                firstProcessor 
= p;
            } 
else {
                
//设置前一个处理器的下一个处理器为当前处理器
                previous.setDefaultNextProcessor(p);
            }

            logger.info(
                
"Processor: " + p.getName() + " --> " + p.getClass().getName());
            
//当前处理器设置为前一个处理器
            previous = p;
        }
    }

    
/** Set the processor chain that the URI should be working through after
     * finishing this one.
     * 设置下一个处理器
     * 
@param nextProcessorChain the chain that should be processed after this
     *        one.
     
*/
    
public void setNextChain(ProcessorChain nextProcessorChain) {
        
this.nextChain = nextProcessorChain;
    }

    
/** Get the processor chain that the URI should be working through after
     * finishing this one.
     *
     * 
@return the next processor chain.
     
*/
    
public ProcessorChain getNextProcessorChain() {
        
return nextChain;
    }

    
/** Get the first processor in the chain.
     * 获取第一个处理器
     * 
@return the first processor in the chain.
     
*/
    
public Processor getFirstProcessor() {
        
return firstProcessor;
    }

 

 

 

(3)ProcessorChainList

该类是保存一次抓取任务的所有的处理器链(ProcessorChain).

 


<!---->package org.archive.crawler.framework;
public class ProcessorChainList {
    
//处理器链列表,保存所有的处理器链
    private List<ProcessorChain> chainList = new ArrayList<ProcessorChain>();
    
//所有的处理器
    private Map<String,ProcessorChain> chainMap
     
= new HashMap<String,ProcessorChain>();

     
/** Add a new chain of processors to the chain list.
     * 将所有的处理器链添加到Map中
     * This method takes a map of processors and wraps it in a ProcessorChain
     * object and adds it to the list of chains.
     *
     * 
@param processorMap the processor map to be added.
     
*/
    
public void addProcessorMap(String name, MapType processorMap) {
        
//由MapType生成一个处理器链
        ProcessorChain processorChain = new ProcessorChain(processorMap);
        ProcessorChain previousChain 
= getLastChain();
        
if (previousChain != null) {
            
//设置下一个处理器链
            previousChain.setNextChain(processorChain);
        }
        chainList.add(processorChain);
        chainMap.put(name, processorChain);
    }

    
/** Get the first processor chain.
     * 获取第一个处理链
     * 
@return the first processor chain.
     
*/
    
public ProcessorChain getFirstChain() {
        
return (ProcessorChain) chainList.get(0);
    }

 

 (4)ToeThread

为了高效抓取网页,Heritrix采用了线程池的设计.每一个线程将调用所有的处理器来处理链接.

 


<!----> private void processCrawlUri() throws InterruptedException {
        currentCuri.setThreadNumber(
this.serialNumber);
        
//获取第一个处理器链
        currentCuri.setNextProcessorChain(controller.getFirstProcessorChain());
        lastStartTime 
= System.currentTimeMillis();
//        System.out.println(currentCuri);
        try {
            
while (currentCuri.nextProcessorChain() != null) {
                setStep(STEP_ABOUT_TO_BEGIN_CHAIN);
                
// Starting on a new processor chain.
                
//设置下一个处理器
                currentCuri.setNextProcessor(currentCuri.nextProcessorChain().getFirstProcessor());
                currentCuri.setNextProcessorChain(currentCuri.nextProcessorChain().getNextProcessorChain());

                
while (currentCuri.nextProcessor() != null) {
                    setStep(STEP_ABOUT_TO_BEGIN_PROCESSOR);
                    Processor currentProcessor 
= getProcessor(currentCuri.nextProcessor());
                    currentProcessorName 
= currentProcessor.getName();
                    continueCheck();
//                    long memBefore = (Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory())/1024;
                    
//调用处理器处理链接
                    currentProcessor.process(currentCuri);
//                    long memAfter = (Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory())/1024;
//                    System.out.println((memAfter-memBefore)+"K in "+currentProcessorName);
                }
            }
            setStep(STEP_DONE_WITH_PROCESSORS);
            currentProcessorName 
= "";
        } 
catch (RuntimeExceptionWrapper e) {
            
// Workaround to get cause from BDB
            if(e.getCause() == null) {
                e.initCause(e.getCause());
            }
            recoverableProblem(e);
        } 
catch (AssertionError ae) {
            
// This risks leaving crawl in fatally inconsistent state, 
            
// but is often reasonable for per-Processor assertion problems 
            recoverableProblem(ae);
        } 
catch (RuntimeException e) {
            recoverableProblem(e);
        } 
catch (StackOverflowError err) {
            recoverableProblem(err);
        } 
catch (Error err) {
            
// OutOfMemory and any others
            seriousError(err); 
        }

 

 

(5)处理器链的初始化

所有的处理器链都是在CrawlController的initialize中初始化的.

 


<!----> public void initialize(SettingsHandler sH)
{

 
//初始化了Scope、Frontier以及ProcessorChain
            setupCrawlModules();

 

 

 


<!---->private void setupCrawlModules(){

        
//设置处理链
        
// Setup processors
        if (processorChains == null) {
            processorChains 
= new ProcessorChainList(order);
        }

 

原始地址:

http://blog.csdn.net/lenolong/archive/2008/12/11/3498645.aspx


评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

文章信息

Global site tag (gtag.js) - Google Analytics