Nutch 2.0 抓取流程介绍
---------------------
InjectorJob => GeneratorJob => FetcherJob => ParserJob => DbUpdaterJob => SolrIndexerJob
InjectorJob : 从文件中得到一批种子网页,把它们放到抓取数据库中去
GeneratorJob: 从抓取数据库中产生要抓取的页面放到抓取队列中去
FetcherJob: 对抓取队列中的网页进行抓取,在reducer中使用了生产/消费者模型
ParserJob: 对抓取完成的网页进行解析,产生一些新的链接与网页内容的解析结果
DbUpdaterJob: 把新产生的链接更新到抓取数据库中去
SolrIndexerJob: 对解析后的内容进行索引建立
下面是InjectorJob的启动函数,代码如下
因为InjectorJob扩展自NutchTool,实现了它的run方法。
我们可以看到,这里有两个MR任务,第一个主要是从文件中读入种子网页,写到DataStore数据库中,第二个MR任务主要是对数据库中的WebPage对象做一个分数与抓取间隔的设置。它使用到一个initMapperJob方法,代码如下
---------------------
1. 整体流程
InjectorJob => GeneratorJob => FetcherJob => ParserJob => DbUpdaterJob => SolrIndexerJob
InjectorJob : 从文件中得到一批种子网页,把它们放到抓取数据库中去
GeneratorJob: 从抓取数据库中产生要抓取的页面放到抓取队列中去
FetcherJob: 对抓取队列中的网页进行抓取,在reducer中使用了生产/消费者模型
ParserJob: 对抓取完成的网页进行解析,产生一些新的链接与网页内容的解析结果
DbUpdaterJob: 把新产生的链接更新到抓取数据库中去
SolrIndexerJob: 对解析后的内容进行索引建立
2. InjectorJob分析
下面是InjectorJob的启动函数,代码如下
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 = 2;
currentJobNum = 0;
status.put(Nutch.STAT_PHASE, "convert input");
currentJob = new NutchJob(getConf(), "inject-p1 " + input);
FileInputFormat.addInputPath(currentJob, input);
// mapper方法,从文件中解析出url,写入数据库
currentJob.setMapperClass(UrlMapper.class);
currentJob.setMapOutputKeyClass(String.class);
// map 的输出为WebPage,它是用Gora compile生成的,可以通过Gora把它映射到不同的数据库中,
currentJob.setMapOutputValueClass(WebPage.class);
// 输出到GoraOutputFormat
currentJob.setOutputFormatClass(GoraOutputFormat.class);
DataStore<String, WebPage> store = StorageUtils.createWebStore(currentJob.getConfiguration(),
String.class, WebPage.class);
GoraOutputFormat.setOutput(currentJob, store, true);
currentJob.setReducerClass(Reducer.class);
currentJob.setNumReduceTasks(0);
currentJob.waitForCompletion(true);
ToolUtil.recordJobStatus(null, currentJob, results);
currentJob = null;
status.put(Nutch.STAT_PHASE, "merge input with db");
status.put(Nutch.STAT_PROGRESS, 0.5f);
currentJobNum = 1;
currentJob = new NutchJob(getConf(), "inject-p2 " + input);
StorageUtils.initMapperJob(currentJob, FIELDS, String.class,
WebPage.class, InjectorMapper.class);
currentJob.setNumReduceTasks(0);
ToolUtil.recordJobStatus(null, currentJob, results);
status.put(Nutch.STAT_PROGRESS, 1.0f);
return results;
}
因为InjectorJob扩展自NutchTool,实现了它的run方法。
我们可以看到,这里有两个MR任务,第一个主要是从文件中读入种子网页,写到DataStore数据库中,第二个MR任务主要是对数据库中的WebPage对象做一个分数与抓取间隔的设置。它使用到一个initMapperJob方法,代码如下
public static <K, V> void initMapperJob(Job job,