|
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
|
|
|