`
h140465
  • 浏览: 21884 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Nutch2源码研究之InjectorJob

阅读更多

Nutch任务通常从InjectorJob开始,它的作用是从种子文件中取出所有种子存入库中,供之后的任务使用。

InjectorJob类中最重要是UrlMapper,这个类实际处理类

public static class UrlMapper extends
      Mapper<LongWritable, Text, String, WebPage> {
    private URLNormalizers urlNormalizers;
    private int interval;//重新抓取同一个页面的时间间隔(默认为30天)
    private float scoreInjected;//一个新页面的默认score
    private URLFilters filters;//url过滤器
    private ScoringFilters scfilters;
    private long curTime;

    @Override
    protected void setup(Context context) throws IOException, InterruptedException {
      urlNormalizers = new URLNormalizers(context.getConfiguration(),
        URLNormalizers.SCOPE_INJECT);
      interval = context.getConfiguration().getInt("db.fetch.interval.default",
        2592000);
      filters = new URLFilters(context.getConfiguration());
      scfilters = new ScoringFilters(context.getConfiguration());
      scoreInjected = context.getConfiguration().getFloat("db.score.injected",
        1.0f);
      curTime = context.getConfiguration().getLong("injector.current.time",
        System.currentTimeMillis());
    }

    protected void map(LongWritable key, Text value, Context context)
        throws IOException, InterruptedException {
      String url = value.toString(); // value is line of text
      //以#开头的忽略
      if (url != null && url.trim().startsWith("#")) {
        /* Ignore line that start with # */
        return;
      }

      //每个url后面都可以加上name=value格式的自定义参数,以tab键分割
      // if tabs : metadata that could be stored
      // must be name=value and separated by \t
      float customScore = -1f;
      int customInterval = interval;
      //解析url后的自定义参数
      Map<String, String> metadata = new TreeMap<String, String>();
      if (url.indexOf("\t") != -1) {
        String[] splits = url.split("\t");
        url = splits[0];//url地址
        for (int s = 1; s < splits.length; s++) {
          // find separation between name and value
          int indexEquals = splits[s].indexOf("=");
          if (indexEquals == -1) {
            // skip anything without a =
            continue;
          }
          String metaname = splits[s].substring(0, indexEquals);
          String metavalue = splits[s].substring(indexEquals + 1);
          //自定义score的值
          if (metaname.equals(nutchScoreMDName)) {
            try {
              customScore = Float.parseFloat(metavalue);
            } catch (NumberFormatException nfe) {
            }
            //自定义抓取间隔时间(单位为秒)
          } else if (metaname.equals(nutchFetchIntervalMDName)) {
            try {
              customInterval = Integer.parseInt(metavalue);
            } catch (NumberFormatException nfe) {
            }
          } else
        	//其他自定义参数
            metadata.put(metaname, metavalue);
        }
      }
      try {
    	//转换成标准格式的url
        url = urlNormalizers.normalize(url, URLNormalizers.SCOPE_INJECT);
        //对url进行过滤,如果不符合规则,返回null
        url = filters.filter(url); // filter the url
      } catch (Exception e) {
        LOG.warn("Skipping " + url + ":" + e);
        url = null;
      }
      if (url == null) {
    	//累加总过滤的url数量
        context.getCounter("injector", "urls_filtered").increment(1);
        return;
      } else {                                         // if it passes
      String reversedUrl = TableUtil.reverseUrl(url);  // collect it
      WebPage row = new WebPage();
      row.setFetchTime(curTime);
      row.setFetchInterval(customInterval);

      // now add the metadata
      Iterator<String> keysIter = metadata.keySet().iterator();
      while (keysIter.hasNext()) {
        String keymd = keysIter.next();
        String valuemd = metadata.get(keymd);
        row.putToMetadata(new Utf8(keymd), ByteBuffer.wrap(valuemd.getBytes()));
      }

      if (customScore != -1)
        row.setScore(customScore);
      else
        row.setScore(scoreInjected);

      try {
        scfilters.injectedScore(url, row);
      } catch (ScoringFilterException e) {
        if (LOG.isWarnEnabled()) {
          LOG.warn("Cannot filter injected score for url " + url
          + ", using default (" + e.getMessage() + ")");
        }
      }
      //累加inject的url数量
      context.getCounter("injector", "urls_injected").increment(1);
      //设置标记
      row.putToMarkers(DbUpdaterJob.DISTANCE, new Utf8(String.valueOf(0)));
      Mark.INJECT_MARK.putMark(row, YES_STRING);
      //将row写入数据库
      context.write(reversedUrl, row);
    }
    }
  }

     InjectorJob类中run(Map<String,Object> args),Crawler中实际是调用这个方法

public Map<String,Object> run(Map<String,Object> args) throws Exception {
    getConf().setLong("injector.current.time", System.currentTimeMillis());
    Path input;
    //从入参中获得种子文件
    Object path = args.get(Nutch.ARG_SEEDDIR);
    if (path instanceof Path) {
      input = (Path)path;
    } else {
      input = new Path(path.toString());
    }
    numJobs = 1;
    currentJobNum = 0;
    currentJob = new NutchJob(getConf(), "inject " + input);
    FileInputFormat.addInputPath(currentJob, input);
    currentJob.setMapperClass(UrlMapper.class);//处理Map
    currentJob.setMapOutputKeyClass(String.class);
    currentJob.setMapOutputValueClass(WebPage.class);
    currentJob.setOutputFormatClass(GoraOutputFormat.class);//输出处理类
    
    DataStore<String, WebPage> store = StorageUtils.createWebStore(currentJob.getConfiguration(),
      String.class, WebPage.class);
    GoraOutputFormat.setOutput(currentJob, store, true);
    
    // NUTCH-1471 Make explicit which datastore class we use
    //获取持久化处理类
    Class<? extends DataStore<Object, Persistent>> dataStoreClass = 
      StorageUtils.getDataStoreClass(currentJob.getConfiguration());
    LOG.info("InjectorJob: Using " + dataStoreClass + " as the Gora storage class.");
    
    currentJob.setReducerClass(Reducer.class);
    currentJob.setNumReduceTasks(0);
    
    currentJob.waitForCompletion(true);
    ToolUtil.recordJobStatus(null, currentJob, results);

    // NUTCH-1370 Make explicit #URLs injected @runtime
    long urlsInjected = currentJob.getCounters().findCounter("injector", "urls_injected").getValue();
    long urlsFiltered = currentJob.getCounters().findCounter("injector", "urls_filtered").getValue();
    LOG.info("InjectorJob: total number of urls rejected by filters: " + urlsFiltered);
    LOG.info("InjectorJob: total number of urls injected after normalization and filtering: "
        + urlsInjected);

    return results;
  }

 

 

1
1
分享到:
评论

相关推荐

    apache-nutch的源码

    Nutch 源码的分析和理解对于想要深入研究搜索引擎工作原理、网页抓取技术和大数据处理的开发者来说至关重要。 在`apache-nutch-2.2.1`这个压缩包中,你将找到以下关键组成部分: 1. **源代码结构**:Nutch 的源...

    nutch1.6源码

    Nutch 1.6 是一个开源的网络爬虫项目,由Apache软件基金会开发,主要用于抓取、索引和搜索Web内容。...通过阅读和研究源码,可以提升对这些技术的理解,并能为开发自己的爬虫或搜索引擎项目打下坚实基础。

    nutch_src 源码 tar—zip格式

    总的来说,Nutch的源码对于学习和研究搜索引擎技术提供了宝贵的资源。通过深入分析和实践,你可以了解到网络爬虫的实现细节,掌握如何处理大规模数据,以及如何构建高效、可扩展的搜索系统。同时,了解和掌握tar和...

    Nutch 1.2源码阅读

    ### Nutch 1.2 源码阅读深入解析 #### Crawl类核心作用与流程概览 在深入了解Nutch 1.2源码之前,我们先明确Nutch的架构和工作流程。Nutch作为一款开源搜索引擎框架,其功能涵盖网页抓取、索引构建以及查询处理。...

    Lucene+Nutch搜索源码

    Lucene+nuctch一书的全部源码 测试源码 和几个简单的项目 (Lucene+ Nuctch a book all the source code and test a few simple items)

    myeclipse8.5导入nutch1.2源码

    2. **Nutch 1.2 源码**:下载 Nutch 1.2 的完整源码包。 3. **Cygwin 环境**:由于 Nutch 是基于 Linux 环境开发的,因此在 Windows 下运行 Nutch 需要通过 Cygwin 来模拟 Linux 命令行环境。 #### 三、导入 Nutch ...

    nutch-1.9 源码

    2. **分块机制**:Nutch采用了分块(Segment)的概念,将抓取的网页数据分割成多个小块存储,便于分布式处理和提高抓取效率。 3. **URL管理**:Nutch有一个URL管理系统,负责跟踪哪些URL已经被抓取,哪些需要抓取,...

    Lucene+Nutch本书源码+详细说明

    这个文件可以用来研究Nutch如何跟踪和管理已访问、待访问的URL,以及如何进行深度优先或广度优先的爬取策略。 而"Lucene+Nutch搜索"可能包含了整个搜索引擎系统的实现,包括Lucene的索引构建部分和Nutch的爬取部分...

    nutch-1.5.1源码

    在研究Nutch-1.5.1源码时,开发者可以学习到以下知识点: 1. **网络爬虫的设计与实现**:理解网页抓取的基本流程,包括URL管理、下载策略和网页解析。 2. **大规模文本处理**:了解如何使用Hadoop进行分布式计算,...

    lucene+nutch搜索引擎开发源码1

    《lucene+nutch搜索引擎开发源码1》是一个包含开源搜索引擎项目Lucene和Nutch源代码的压缩包,主要针对搜索引擎开发的学习和实践。这个压缩包是书籍《lucene+nutch搜索引擎开发》的一部分,由于源码量较大,因此分为...

    Lucene nutch 搜索引擎 开发 实例 源码

    通过学习和研究这些源码,开发者不仅可以了解搜索引擎的基本原理,还能掌握如何在实际项目中应用这些技术。对于初学者来说,详细注释的示例代码提供了很好的学习资源,有助于理解Lucene和Nutch的内部工作机制。同时...

    Lucene+Nutch搜索源码.part1.rar

    Lucene+Nutch搜索源码.part1.rar Lucene+Nutch搜索源码.part2.rar

    Lucene+Nutch搜索源码.part2.rar

    Lucene+Nutch搜索源码.part1.rar rar 货真价实 希望对你有帮助

    nutch2.2.1-src

    通过学习和研究Nutch源码,开发者不仅可以了解网络爬虫的工作流程,还可以学习到分布式计算、文本处理、搜索算法等多方面的知识。这对于构建自己的搜索引擎系统,或者在大数据领域进行深度开发有着极大的帮助。同时...

    Nutch源码研究

    Nutch 的源码研究对于理解搜索引擎的工作原理和网页抓取技术非常有帮助。通过深入分析源码,开发者可以自定义抓取策略、优化性能,甚至开发新的协议插件以支持更多数据源。同时,Nutch 的设计思路也可以为其他分布式...

    nutch-1.3源码

    通过深入研究 Nutch-1.3 的源码,不仅可以掌握网络爬虫的基本原理和技术,还能提升在 Java、Hadoop 和搜索引擎领域的专业技能。这对于从事大数据处理、搜索引擎开发或者网络信息挖掘的开发者来说,具有极高的学习...

    nutch1.2源码

    要使用Nutch 1.2,你需要先安装Hadoop环境,然后编译Nutch源码,配置相应的参数,设置爬取种子,启动爬虫,最后进行索引和搜索。这个过程涉及的文件包括`conf`目录下的配置文件,如`nutch-site.xml`,以及`bin`目录...

    Nutch_插件深入研究

    ### Nutch插件深入研究 #### 一、Nutch插件概述 Nutch是一个开源的Web爬虫项目,由Apache软件基金会维护。它基于Hadoop,能够从互联网上抓取和索引网页,构建搜索引擎。Nutch的强大之处在于其高度可定制性,这主要...

    Lucee+Nutch搜索(源码2)

    其他源码在: Lucee+Nutch搜索(源码1)那里,因为文件太大了.  12.5 企业信息索引   12.5.1 数据索引建立   12.5.2 信息检索代码   12.5.3 检索Web代码   12.5.4 检索结果测试   12.6 小结

Global site tag (gtag.js) - Google Analytics