zsyzhou 发表于 2015-7-30 15:58:50

Apache Nutch 1.3 学习笔记六(ParseSegment)

  
1. bin/nutch parse
  这个命令主要是用来解析抓取的内容,对其进行外链接分析,计算分数等操作,这个解析在抓取的时候就可以设置是否进行,如果在抓取的时候没有设置解析抓取的网页内容,那这边可以单独用一个Map-Reduce任务来做。
后面的参数为:Usage: ParseSegment segment
这里是一个segment的目录名

2. ParseSegment源代码分析
2.1 任务的启动
  ParseSegment任务的启动也是用一个Map-Reduce任务的,下面是它的源代码
  

[*]
// 配置一个Job
[*]
JobConf job = new NutchJob(getConf());
[*]
   job.setJobName("parse " + segment);
[*]
[*]
[*]
   // add content directory to FileInputFormat path
[*]
// 把segment目录下的content目录加入输入路径中
[*]
   FileInputFormat.addInputPath(job, new Path(segment, Content.DIR_NAME));
[*]
   job.set(Nutch.SEGMENT_NAME_KEY, segment.getName());
[*]
   // set input format
[*]
// 设置输入格式
[*]
   job.setInputFormat(SequenceFileInputFormat.class);
[*]
// 设置Map-Reduce方法
[*]
   job.setMapperClass(ParseSegment.class);
[*]
   job.setReducerClass(ParseSegment.class);
[*]
[*]
// 设置输出路径
[*]
   FileOutputFormat.setOutputPath(job, segment);
[*]
   // Parse Output Format to output
[*]
// 设置输出格式
[*]
   job.setOutputFormat(ParseOutputFormat.class);
[*]
// 设置输出的类型
[*]
   job.setOutputKeyClass(Text.class);
[*]
// NOTE:这里注意一下,输出的value为ParseImpl,而ParseOutputFormat的输出为Parse,
[*]
// 这里的ParseImpl是实现Parse接口的,是is-a的关系
[*]
   job.setOutputValueClass(ParseImpl.class);
[*]
[*]
[*]
   JobClient.runJob(job);
  
2.2 ParseSegment类中的Map与Reduce分析
  这个类主要是用来分析content中的内容,它实现了Mapper与Reducer接口
在Mapper中,主要是对content内容进行调用相应的插件进行解析,产生一个ParseResult,再遍历这个ParseResult,把其中解析出来的内容collect出去。这个ParseResult是一个收集解析结果的容器,其元素为对,这里解析可能产生多个这样的输出元素对,因为这里可能有多个内容与原url进行关联,所以就有可能产生多个输出
这里的Reduce很有趣,只是收集第一个对,还不知道是为什么,可能是因为它认为第一个的权重最大吧。如果有谁知道的,请告诉我一下。

2.3 ParseOutputFormat的分析
  我们知道,在写关于Map-Reduce的时候,有时我们想自己控制输出的源,这里你就要实现其架构提供的OutputFormat,前提是你没有找到合适的输出方法,因为Hadoop框架提出了几个常用的OutputFormat方法。
在实现的OutputFormat接口,主要是实现一个叫getRecordWriter,这个方法返回一个自定义的RecordWriter的子类,用用于写出Reducer的输出对,注意一下,在Hadoop架构中,一个也叫一条记录。

下面我们来分析一下这个getReocrdWriter方法,源代码如下:
呵呵,不要被吓到,一步步分析,老外的代码还是很好看的
  

[*]
public RecordWriter getRecordWriter(FileSystem fs, JobConf job,
[*]
                                     String name, Progressable progress) throws IOException {
[*]
[*]
[*]
// 这里根据配置生成一个url过滤器
[*]
   this.filters = new URLFilters(job);
[*]
// 这里生成一个url的规格化对象
[*]
   this.normalizers = new URLNormalizers(job, URLNormalizers.SCOPE_OUTLINK);
[*]
// 这里生成一个分数计算器
[*]
   this.scfilters = new ScoringFilters(job);
[*]
// 配置url的抓取间隔
[*]
   final int interval = job.getInt("db.fetch.interval.default", 2592000);
[*]
// 得到是否要解析外链接
[*]
   final boolean ignoreExternalLinks = job.getBoolean("db.ignore.external.links", false);
[*]
// 得到每一个网页外链接的解析个数,默认是100个,
[*]
   int maxOutlinksPerPage = job.getInt("db.max.outlinks.per.page", 100);
[*]
   final int maxOutlinks = (maxOutlinksPerPage
页: [1]
查看完整版本: Apache Nutch 1.3 学习笔记六(ParseSegment)