首页 > 其他分享 >Heritrix架构学习笔记(三)

Heritrix架构学习笔记(三)

时间:2023-09-07 14:36:45浏览次数:31  
标签:架构 Heritrix 笔记 public controller long return 链接 cURI


3、Frontier链接制造工厂

在heritrix- 1.12.1 /docs/articles/developer_manual/frontier.html下可找到Heritrix的官方文档的一个Frontier例子:

/**       
 * A simple Frontier implementation for tutorial purposes       
 */       
public class MyFrontier extends ModuleType implements Frontier,       
        FetchStatusCodes {       
// A list of the discovered URIs that should be crawled.       
// 列表用来保存还未抓取的链接        
    List pendingURIs = new ArrayList();       
    
    // A list of prerequisites that needs to be met before any other URI is       
// allowed to be crawled, e.g. DNS-lookups       
//这个列表中保存了一系列的链接,它们的优先级要高于pendingURIs那个List中的任何一个链接,        
//表中的链接表示一些需要被满足的先决条件        
    List prerequisites = new ArrayList();       
    
// A hash of already crawled URIs so that every URI is crawled only once.       
//一个HashMap,用于存储那些已经抓取过的链接        
    Map alreadyIncluded = new HashMap();       
    
// Reference to the CrawlController.       
// CrawlController对象        
    CrawlController controller;       
                       
// Flag to note if a URI is being processed.       
//用于标识是否一个链接正在被处理        
    boolean uriInProcess = false;       
    
// top-level stats       
//成功下载的数量        
long successCount = 0;       
//失败的数量        
long failedCount = 0;       
//抛弃掉链接的数量        
long disregardedCount = 0;       
//总共下载的字节数        
    long totalProcessedBytes = 0;       
                       
    public MyFrontier(String name) {       
        super(Frontier.ATTR_NAME, "A simple frontier.");       
    }       
                       
    public void initialize(CrawlController controller)       
            throws FatalConfigurationException, IOException {       
        //注入        
        this.controller = controller;       
        
        // Initialize the pending queue with the seeds       
        //把种子文件中的链接加入到pengdingURIs中去        
        this.controller.getScope().refreshSeeds();       
        List seeds = this.controller.getScope().getSeedlist();       
        synchronized(seeds) {       
            for (Iterator i = seeds.iterator(); i.hasNext();) {       
                UURI u = (UURI) i.next();       
                CandidateURI caUri = new CandidateURI(u);       
                caUri.setSeed();       
                schedule(caUri);       
            }       
        }       
    }       
                       
    //该方法是给线程池中的线程调用的,用以取出下一个准备处理的链接        
    public synchronized CrawlURI next(int timeout) throws InterruptedException {       
        if (!uriInProcess && !isEmpty()) {       
            uriInProcess = true;       
            CrawlURI curi;       
            /*       
             先看prerequistes队列中是否有要处理的链接,如果有,就先处理,如果没有,再看pengdingURIs队列中是否有链接。每次在处理的时候,总是取出队列中的第一个链接        
            */       
            if (!prerequisites.isEmpty()) {       
                curi = CrawlURI.from((CandidateURI) prerequisites.remove(0));       
            } else {       
                curi = CrawlURI.from((CandidateURI) pendingURIs.remove(0));       
            }       
            curi.setServer(controller.getServerCache().getServerFor(curi));       
            return curi;       
        } else {       
            wait(timeout);       
            return null;       
        }       
    }       
       public boolean isEmpty() {       
        return pendingURIs.isEmpty() && prerequisites.isEmpty();       
    }       
                       
     //该方法用于将新链接加入到pengdingURIs队列中,等待处理        
    public synchronized void schedule(CandidateURI caURI) {       
        // Schedule a uri for crawling if it is not already crawled       
       /*       
          首先判断要加入的链接是否已经被抓取过,如果已经包含在alreadyIncluded这个HashMap中则说明处理过了,就可以放弃处理        
       */       
        if (!alreadyIncluded.containsKey(caURI.getURIString())) {       
            if(caURI.needsImmediateScheduling()) {       
                prerequisites.add(caURI);       
            } else {       
                pendingURIs.add(caURI);       
            }       
            //HashMap中使用url的字符串来作为key,而将实际的CadidateURI对象作为value        
            alreadyIncluded.put(caURI.getURIString(), caURI);       
        }       
    }       
                       
    public void batchSchedule(CandidateURI caURI) {       
        schedule(caURI);       
    }       
                       
    public void batchFlush() {       
    }       
                       
    //一次抓取结束后所执行的操作,该操作由线程池中的线程来进行调用        
    public synchronized void finished(CrawlURI cURI) {       
        uriInProcess = false;       
        //成功下载        
        if (cURI.isSuccess()) {       
            
            successCount++;       
            //统计下载总数        
            totalProcessedBytes += cURI.getContentSize();       
            //如果成功,则触发一个成功事件,比如将Extractor解析出来的新URL加入队列中        
            controller.fireCrawledURISuccessfulEvent(cURI);       
            cURI.stripToMinimal();       
        }       
         //需要推迟下载        
else if (cURI.getFetchStatus() == S_DEFERRED) {       
            cURI.processingCleanup();       
            alreadyIncluded.remove(cURI.getURIString());       
            schedule(cURI);       
        }       
        //其他状态        
else if (cURI.getFetchStatus() == S_ROBOTS_PRECLUDED       
                || cURI.getFetchStatus() == S_OUT_OF_SCOPE       
                || cURI.getFetchStatus() == S_BLOCKED_BY_USER       
                || cURI.getFetchStatus() == S_TOO_MANY_EMBED_HOPS       
                || cURI.getFetchStatus() == S_TOO_MANY_LINK_HOPS       
                || cURI.getFetchStatus() == S_DELETED_BY_USER) {       
            //抛弃当前URI        
            controller.fireCrawledURIDisregardEvent(cURI);       
            disregardedCount++;       
            cURI.stripToMinimal();       
        } else {       
            controller.fireCrawledURIFailureEvent(cURI);       
            failedCount++;       
            cURI.stripToMinimal();       
        }       
        cURI.processingCleanup();       
    }       
                       
    //返回所有已经处理过的链接数量        
    public long discoveredUriCount() {       
        return alreadyIncluded.size();       
    }       
                       
   //返回所有等待处理的链接数量        
    public long queuedUriCount() {       
        return pendingURIs.size() + prerequisites.size();       
    }       
                       
    //返回所有已经完成的链接数量        
    public long finishedUriCount() {       
        return successCount + failedCount + disregardedCount;       
    }       
    
    //返回所有成功处理的链接数量        
    public long successfullyFetchedCount() {       
        return successCount;       
    }       
   
    //返回所有失败的链接数量        
    public long failedFetchCount() {       
        return failedCount;       
    }       
    //返回所有抛弃的链接数量        
    public long disregardedFetchCount() {       
        return disregardedCount;       
    }       
   //返回总共下载的字节数        
    public long totalBytesWritten() {       
        return totalProcessedBytes;       
    }       
                       
    public String report() {       
        return "This frontier does not return a report.";       
    }       
                       
    public void importRecoverLog(String pathToLog) throws IOException {       
        throw new UnsupportedOperationException();       
    }       
                       
    public FrontierMarker getInitialMarker(String regexpr,       
            boolean inCacheOnly) {       
        return null;       
    }       
                       
    public ArrayList getURIsList(FrontierMarker marker, int numberOfMatches,       
            boolean verbose) throws InvalidFrontierMarkerException {       
        return null;       
    }       
                       
    public long deleteURIs(String match) {       
        return 0;       
    }       
                       
}

注意:上面仅仅是一个最基础的代码,从结构上揭示一个Frontier的作用

标签:架构,Heritrix,笔记,public,controller,long,return,链接,cURI
From: https://blog.51cto.com/u_2544485/7396870

相关文章

  • Heritrix架构学习笔记(一)
    1、抓取起点CrawlOrder在heritrix-1.12.1/docs/apidocs目录下可以查看其API:org.archive.crawler.datamodelClassCrawlOrderjava.lang.Objectjavax.management.Attributeorg.archive.crawler.settings.Typeorg.archive.crawler.settings.Complex......
  • heritrix配置篇
    目前对Heritrix做了初步选型测试,有了一些总结:1.关于安装:     目前的版本号为1.12.1,官网地址为 http://crawler.archive.org/。常规安装,即解压到相关目录,之后配置系统环境变量"HERITRIX_HOME"到该解压目录(Java环境已经配置好)。2.安装的后续工作:     将%HERIT......
  • [个人笔记][C#]异步调用控制流的一些测试结论
    await调用逻辑总结如下:调用线程A执行到await时,在await处返回并继续执行调用点后面的代码,await处新开一个线程B执行task线程B执行完task后继续执行await后面的代码如果再次遇到await,线程B在await处返回,新开一个线程C执行task线程C执行完task后继续执行await后面的代码"新开......
  • sqlserver移植为Oracle笔记(更新,新增字段名;批量新增记录;日期查询;截取字串函数)
    下面是这两天在项目要sqlserver和oracle兼容的改造中测试出来的笔记:--sqlserver--更改主键字段名'ID'为'ID_'sp_rename  'tb_doc_cat_statistic.ID','ID_','column'--新增字段cat_codealtertabletb_doc_cat_statisticaddcat_codevarchar(100) --oracle--......
  • 【刷题笔记】
    题目Givenacollectionofcandidatenumbers(candidates)andatargetnumber(target),findalluniquecombinationsin candidates wherethecandidatenumberssumsto target.Eachnumberin candidates mayonlybeused once inthecombination.Note:All......
  • RK3568开发笔记(七):在宿主机ubuntu上搭建Qt交叉编译开发环境,编译一个Demo,目标板运行Demo
    前言  在之前的博文中已经搭建好了一个比较完善的ubuntu宿主机,都很完善了但是发现没有Qt交叉编译开发环境,所以还需要搭建一套Qt交叉编译开发环境。<br>补充说明  本篇是基于《RK3568开发笔记(三):RK3568虚拟机基础环境搭建之更新源、安装网络工具、串口调试、网络连接、文件传......
  • 智能车---stc8学习笔记1
    采集状态,调整车身--控制电机,传感器获取偏差信息,根据控制逻辑实现电机驱动,采集决策执行  电源电路,稳压电路,保护时钟电路,给单片机提供时钟,心跳,而且确定了单片机工作的速度复位电路,上电重启    串行是一串一串发送数据定时器:很多事情不是来了才做,有......
  • RK3568开发笔记(七):在宿主机ubuntu上搭建Qt交叉编译开发环境,编译一个Demo,目标板运行Demo
    前言  在之前的博文中已经搭建好了一个比较完善的ubuntu宿主机,都很完善了但是发现没有Qt交叉编译开发环境,所以还需要搭建一套Qt交叉编译开发环境。 补充说明  本篇是基于《RK3568开发笔记(三):RK3568虚拟机基础环境搭建之更新源、安装网络工具、串口调试、网络连接、......
  • Sermant类隔离架构解析——解决JavaAgent场景类冲突的实践
    一、JavaAgent场景为什么要注意类冲突问题?类冲突问题并非仅存在于JavaAgent场景中,在Java场景中一直都存在,该问题通常会导致运行时触发NoClassDefFoundError、ClassNotFoundException、NoSuchMethodError等异常。从使用场景来看,基于JavaAgent技术所实现的工具,往往用于监控、治理等场......
  • Upload靶场通关笔记-特殊解析后缀
    特殊解析后缀  提 示本pass禁止上传.asp|.aspx|.php|.jsp后缀文件!  //后缀黑名单//t用于删除字符串的头尾空白符,空白符包括:空格、制表符tab、换行符等其他空白符等。//函数用于查找某字符在字符串中最后一次出现的位置将最后一个点前面的内容全部删掉  php......