?。ㄒ韵路治鲠槍Φ氖?nutch 1.4)
Crawl 類是運行抓取程序的入口,代碼不多,但關(guān)聯(lián)的其他類不少。
抓取的流程是:
1. 將初始的 URL 地址注入到 crawlDb
2. 從crawldb中生成一個url的子集用于抓取
3. 抓取網(wǎng)頁
4. 分析網(wǎng)頁
5. 更新 crawlDb ,增加新抓取的 url
6. 循環(huán)執(zhí)行 2-5 步,直到達到指定的抓取深度
之后,還需要進行鏈接反轉(zhuǎn),將索引導入到 solr 等。
Crawl 類的聲明如下:
Configured 和 Tool 是 hadoop 中的概念
Configured 是 hadoop 中用來提供配置信息的,在 ToolRunner.run 方法中,會將創(chuàng)建好的 Configuration 對象通過 Configured.setConf 方法注入到 Crawl 中。
Tool 是 hadoop 中用來處理命令行參數(shù)并修改 Map-Reduce 任務(wù)的參數(shù),它需要在 run 方法中處理這些命令行參數(shù)。
因為 Crawl 實現(xiàn)了 Tool 接口,我們可以通過命令行啟動數(shù)據(jù)抓取的 Map-Reduce 任務(wù)。
啟動 Crawl 的 main 方法如下:
NutchConfiguration.create 會加載 nutch-default.xml 和 nutch-site.xml 中的配置信息生成 Configuration 對象。
ToolRunner.run 方法會將創(chuàng)建好的 Configuration 對象通過 Configured.setConf 方法注入到 Crawl 中(Crawl 繼承了Configured),并將參數(shù)的處理委托給 Tool.run 方法(Crawl 實現(xiàn)了 Tool 接口,因此需要提供 run 方法的實現(xiàn))。
接下來我們重點分析一下 Crawl 類的 run 方法。
首先是參數(shù)的設(shè)置:
這幾個參數(shù)的含義如下:
rootUrlDir : 要抓取的起始 url 所在的目錄
dir : 默認情況下,抓取時生成的文件的目錄
threads : 抓取數(shù)據(jù)的線程數(shù)
depth : 通過外鏈抓取網(wǎng)頁的深度,從起始 url 算起
topN : 每輪抓取獲得的新的 url 中,只對分值最高的 topN 個 url 再次抓取
solrUrl : solr 的地址。用于調(diào)用 solr 的 api 建立用于搜索的索引。
這些參數(shù)是可以根據(jù)命令行的輸入修改的:
然后需要創(chuàng)建抓取程序?qū)⒁玫降膶ο螅?
這里簡要說明一下這些對象的作用:
injector : 將初始的 URL 地址到 crawlDb
generator : 生成要抓取的 URL
fetcher : 抓取網(wǎng)頁
parseSegment : 分析網(wǎng)頁
crawlDbTool : CrawlDb 類的實例,存放將要抓取的 URL
linkDbTool : 用于存放鏈接之間的引用關(guān)系,便于計算權(quán)重
完成以上的準備工作之后,就開始執(zhí)行主要的處理邏輯:
前面通過抓取和分析網(wǎng)頁得到的鏈接格式為 源鏈接 => 目標鏈接,
需要通過反轉(zhuǎn),得到目標鏈接對應(yīng)的源鏈接,以便于計算目標鏈接的權(quán)重等:
最后,如果指定了 solrUrl,需要將 nutch 索引導入到 solr 中
以上只是對源代碼進行字面上的分析,更深入的分析可以參考以下文章:
http://blog.csdn.net/kauu/article/details/1823830
http://www.diybl.com/course/3_program/java/javajs/20100719/459450.html
Crawl 類是運行抓取程序的入口,代碼不多,但關(guān)聯(lián)的其他類不少。
抓取的流程是:
1. 將初始的 URL 地址注入到 crawlDb
2. 從crawldb中生成一個url的子集用于抓取
3. 抓取網(wǎng)頁
4. 分析網(wǎng)頁
5. 更新 crawlDb ,增加新抓取的 url
6. 循環(huán)執(zhí)行 2-5 步,直到達到指定的抓取深度
之后,還需要進行鏈接反轉(zhuǎn),將索引導入到 solr 等。
Crawl 類的聲明如下:
public class Crawl extends Configured implements Tool
Configured 和 Tool 是 hadoop 中的概念
Configured 是 hadoop 中用來提供配置信息的,在 ToolRunner.run 方法中,會將創(chuàng)建好的 Configuration 對象通過 Configured.setConf 方法注入到 Crawl 中。
Tool 是 hadoop 中用來處理命令行參數(shù)并修改 Map-Reduce 任務(wù)的參數(shù),它需要在 run 方法中處理這些命令行參數(shù)。
因為 Crawl 實現(xiàn)了 Tool 接口,我們可以通過命令行啟動數(shù)據(jù)抓取的 Map-Reduce 任務(wù)。
啟動 Crawl 的 main 方法如下:
public static void main(String args[]) throws Exception { // 創(chuàng)建 Configuration 對象 Configuration conf = NutchConfiguration.create(); // 執(zhí)行任務(wù) int res = ToolRunner.run(conf, new Crawl(), args); // 退出程序 System.exit(res); }
NutchConfiguration.create 會加載 nutch-default.xml 和 nutch-site.xml 中的配置信息生成 Configuration 對象。
ToolRunner.run 方法會將創(chuàng)建好的 Configuration 對象通過 Configured.setConf 方法注入到 Crawl 中(Crawl 繼承了Configured),并將參數(shù)的處理委托給 Tool.run 方法(Crawl 實現(xiàn)了 Tool 接口,因此需要提供 run 方法的實現(xiàn))。
接下來我們重點分析一下 Crawl 類的 run 方法。
首先是參數(shù)的設(shè)置:
// 默認參數(shù) Path rootUrlDir = null; Path dir = new Path("crawl-" + getDate()); int threads = getConf().getInt("fetcher.threads.fetch", 10); int depth = 5; long topN = Long.MAX_VALUE; String solrUrl = null;
這幾個參數(shù)的含義如下:
rootUrlDir : 要抓取的起始 url 所在的目錄
dir : 默認情況下,抓取時生成的文件的目錄
threads : 抓取數(shù)據(jù)的線程數(shù)
depth : 通過外鏈抓取網(wǎng)頁的深度,從起始 url 算起
topN : 每輪抓取獲得的新的 url 中,只對分值最高的 topN 個 url 再次抓取
solrUrl : solr 的地址。用于調(diào)用 solr 的 api 建立用于搜索的索引。
這些參數(shù)是可以根據(jù)命令行的輸入修改的:
for (int i = 0; i < args.length; i++) { if ("-dir".equals(args[i])) { dir = new Path(args[i+1]); i++; } else if ("-threads".equals(args[i])) { threads = Integer.parseInt(args[i+1]); i++; } else if ("-depth".equals(args[i])) { depth = Integer.parseInt(args[i+1]); i++; } else if ("-topN".equals(args[i])) { topN = Integer.parseInt(args[i+1]); i++; } else if ("-solr".equals(args[i])) { solrUrl = StringUtils.lowerCase(args[i + 1]); i++; } else if (args[i] != null) { rootUrlDir = new Path(args[i]); } }
然后需要創(chuàng)建抓取程序?qū)⒁玫降膶ο螅?
Path tmpDir = job.getLocalPath("crawl"+Path.SEPARATOR+getDate()); Injector injector = new Injector(getConf()); Generator generator = new Generator(getConf()); Fetcher fetcher = new Fetcher(getConf()); ParseSegment parseSegment = new ParseSegment(getConf()); CrawlDb crawlDbTool = new CrawlDb(getConf()); LinkDb linkDbTool = new LinkDb(getConf());
這里簡要說明一下這些對象的作用:
injector : 將初始的 URL 地址到 crawlDb
generator : 生成要抓取的 URL
fetcher : 抓取網(wǎng)頁
parseSegment : 分析網(wǎng)頁
crawlDbTool : CrawlDb 類的實例,存放將要抓取的 URL
linkDbTool : 用于存放鏈接之間的引用關(guān)系,便于計算權(quán)重
完成以上的準備工作之后,就開始執(zhí)行主要的處理邏輯:
// 初始化 crawlDb // 將初始的 URL 地址到 crawlDb injector.inject(crawlDb, rootUrlDir); int i; // 循環(huán)執(zhí)行,直到達到指定的抓取深度 for (i = 0; i < depth; i++) { // 生成要抓取的 URL Path[] segs = generator.generate(crawlDb, segments, -1, topN, System.currentTimeMillis()); // 沒有需要抓取的 URL 了,提前中止抓取過程 if (segs == null) { LOG.info("Stopping at depth=" + i + " - no more URLs to fetch."); break; } fetcher.fetch(segs[0], threads); // 抓取網(wǎng)頁 if (!Fetcher.isParsing(job)) { parseSegment.parse(segs[0]); // 分析網(wǎng)頁 } crawlDbTool.update(crawlDb, segs, true, true); // 更新 crawldb,增加需要抓取的 URL }
前面通過抓取和分析網(wǎng)頁得到的鏈接格式為 源鏈接 => 目標鏈接,
需要通過反轉(zhuǎn),得到目標鏈接對應(yīng)的源鏈接,以便于計算目標鏈接的權(quán)重等:
linkDbTool.invert(linkDb, segments, true, true, false);
最后,如果指定了 solrUrl,需要將 nutch 索引導入到 solr 中
// 將索引導入到 solr if (solrUrl != null) { // 獲取創(chuàng)建好的 nutch 索引的文件索引 FileStatus[] fstats = fs.listStatus(segments, HadoopFSUtil.getPassDirectoriesFilter(fs)); // 建立 Solr 索引 SolrIndexer indexer = new SolrIndexer(getConf()); indexer.indexSolr(solrUrl, crawlDb, linkDb, Arrays.asList(HadoopFSUtil.getPaths(fstats))); // 去重 SolrDeleteDuplicates dedup = new SolrDeleteDuplicates(); dedup.setConf(getConf()); dedup.dedup(solrUrl); }
以上只是對源代碼進行字面上的分析,更深入的分析可以參考以下文章:
http://blog.csdn.net/kauu/article/details/1823830
http://www.diybl.com/course/3_program/java/javajs/20100719/459450.html