- 浏览: 295815 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (155)
- Liferay portal研究 (23)
- spring研究 (7)
- Displaytag (2)
- Flash Builder (0)
- 搜索引擎 (12)
- 杂项 (17)
- SCM管理 (7)
- Jquery (5)
- Linux (7)
- Oracle (10)
- httpd集成 (3)
- Maven2 (5)
- 企业管理 (1)
- tomcat高级 (4)
- dos命令 (1)
- ldap (2)
- Java (8)
- webservice (1)
- jetty代码研究 (3)
- OpenCMS (1)
- JMX (2)
- hibernate (5)
- Ant (1)
- js tree (4)
- Quartz (0)
- CMS (1)
- springside (1)
- proxool (1)
- freemarker (1)
- Cookie (1)
- CAS SSO (4)
- mysql (1)
- php (1)
- js (2)
- Asset (1)
- openmeeting (1)
- h2数据库 (2)
- wcf vs java ws (1)
最新评论
-
22199143:
...
当在重启Tomcat容器时 Exception in Thread "HouseKeeper" java.lang.NullPointerException -
liuqq:
一直用Oracle开发,几乎没有接触过其他数据库。使用Mysq ...
The Nested Set Model -
yjsxxgm:
yjsxxgm 写道FFFFFFFFFFFFFFFWWW
java 访问wcf -
yjsxxgm:
FFFFFFFFFFFFFFF
java 访问wcf -
hjp222:
scanIntervalSeconds 是重新启动,并非真正的 ...
Jetty 热部署
================================================================
Crawler和Searcher两部分被尽是分开,其主要目的是为了使两个部分可以布地配置在硬件平台上,例如Crawler和Searcher分别被放置在两个主机上,这样可以极大的提高灵活性和性能。
一、总体介绍:
1、先注入种子urls到crawldb
2、循环:
* generate 从crawldb中生成一个url的子集用于抓取
* fetch 抓取上一小的url生成一个个segment
* parse 分析已抓取segment的内容
* update 把已抓取的数据更新到原先的crawldb
3、从已抓取的segments中分析出link地图
4、索引segment文本及inlink锚文本
二、相关的数据结构:
Crawl DB
● CrawlDb 是一个包含如下结构数据的文件:
<URL, CrawlDatum>
● CrawlDatum:
<status, date, interval, failures, linkCount, ...>
● Status:
{db_unfetched, db_fetched, db_gone,linked,
fetch_success, fetch_fail, fetch_gone}
爬虫Crawler:
Crawler 的工作流程包括了整个nutch的所有步骤--injector,generator,fetcher,parseSegment, updateCrawleDB,Invert links, Index ,DeleteDuplicates, IndexMerger
Crawler涉及的数据文件和格式和含义,和以上的各个步骤相关的文件分别被存放在物理设备上的以下几个文件夹里,crawldb,segments,indexes,linkdb,index五个文件夹里。
那么各个步骤和流程是怎么,各个文件夹里又是放着什么呢?
观察Crawler类可以知道它的流程
./nutch crawl urls -dir ~/crawl -depth 4 -threads 10 -topN 2000
1、Injector injector = new Injector(conf);
Usage: Injector <crawldb> <url_dir>
首先是建立起始url集,每个url都经过URLNormalizers、filter和scoreFilter三个过程并标记状态。首先经过normalizer plugin,把url进行标准化,比如basic nomalizer的作用有把大写的url标准化为小写,把空格去除等等。然后再经过的plugin 是filter,可以根据你写的正则表达式把想要的url留下来。经过两个步骤后,然后就是把这个url进行状态标记,每个url都对应着一个 CrawlDatum,这个类对应着每个url在所有生命周期内的一切状态。细节上还有这个url处理的时间和初始时的分值。
同时,在这个步骤里,会在文件系统里生成 如下文件 crawlDB\current\part-00000
这个文件夹里还有.data.crc , .index.crc, data, index四个文件
● MapReduce1: 把输入的文件转换成DB格式
In: 包含urls的文本文件
Map(line) → <url, CrawlDatum>; status=db_unfetched
Reduce() is identity;
Output: 临时的输出文件夹
● MapReduce2: 合并到现有的DB
Input: 第一步的输出和已存在的DB文件
Map() is identity.
Reduce: 合并CrawlDatum成一个实体(entry)
Out: 一个新的DB
2、Generator generator = new Generator(conf); //Generates a subset of a crawl db to fetch
Usage: Generator <crawldb> <segments_dir> [-force] [-topN N] [-numFetchers numFetchers] [-adddays numDays] [-noFilter]
在这个步骤里,Generator一共做了四件事情,
1、给前面injector完成的输出结果里按分值选出前topN个url,作为一个fetch的子集。
2、根据第一步的结果检查是否已经选取出一些url,CrawlDatum的实体集。
3、再次转化,此次要以url的host来分组,并以url的hash来排序。
4、根据以上的步骤的结果来更新crawldb(injector产生)。
● MapReduce1: 根据要求选取一些要抓取的url
In: Crawl DB 文件
Map() → if date≥now, invert to <CrawlDatum, url>
Partition 以随机的hash值来分组
Reduce:
compare() 以 CrawlDatum.linkCount的降序排列
output only top-N most-linked entries
● MapReduce2: 为下一步抓取准备
Map() is invert; Partition() by host, Reduce() is identity.
Out: 包含<url,CrawlDatum> 要并行抓取的文件
3、Fetcher fetcher = new Fetcher(conf); //The fetcher. Most of the work is done by plugins
Usage: Fetcher <segment> [-threads n] [-noParsing]
这个步骤里,Fetcher所做的事情主要就是抓取了,同时也完成一些其它的工作。首先,这是一个多线程的步骤,默认以10个线程去抓取。根据抓取回来后的结果状态来进行不同的标记,存储,再处理等等行为。输入是上一步骤Generator产生的segment文件夹,这个步骤里,考虑到先前已经按照ip 或host来patition了,所以在此就不再把input文件进行分割了。程序继承了SequenceFileInputFormat重写了 inputFormat来达到这点。这个类的各种形为都是插件来具体完成的,它只是一个骨架一样为各种插件提供一个平台。它先根据url来取出具体的 protocol,得到protocolOutput,进而得到状态status及内容content。然后,根据抓取的状态status来继续再处理。再处理时,首先会将这次抓取的内容content、状态status及它的状态标记进行存储。这个存储的过程中,还会记下抓取的时间,再把segment 存过metadata,同时在分析parsing前经过scoreFilter,再用parseUtil(一系列的parse插件)进行分析,分析后再经过一次score插件的处理。经过这一系列处理后,最后进行输出(url,fetcherOutput)。
之前讲到根据抓取回来的各种状态,进行再处理,这些状态一共包括12种,比如当抓取成功时,会像上刚讲的那样先存储结果,再判断是否是链接跳转,跳转的次数等等处理。
● MapReduce:抓取
In: <url,CrawlDatum>, 以host分区, 以hash值排序
Map(url,CrawlDatum) → <url, FetcherOutput>
多线程的, 同步的map实现
调用已有的协议protocol插件
FetcherOutput: <CrawlDatum, Content>
Reduce is identity
Out: 两个文件: <url,CrawlDatum>, <url,Content>
4、 ParseSegment parseSegment = new ParseSegment(conf); //Parse content in a segment
Usage: ParseSegment segment
对于这个步骤的逻辑比较简单,只是对抓取后上一步骤存储在segment里的content进行分析parse。同样,这个步骤的具体工作也是由插件来完成的。
MapReduce: 分析内容
In: <url, Content> 抓取来的内容
Map(url, Content) → <url, Parse>
调用分析插件parser plugins
Reduce is identity.
Parse: <ParseText, ParseData>
Out: 分割成三个文件: <url,ParseText>, <url,ParseData> 和<url,CrawlDatum> 为了outlinks.
5、CrawlDb crawlDbTool = new CrawlDb(conf); //takes the output of the fetcher and updates the crawldb accordingly.
Usage: CrawlDb <crawldb> (-dir <segments> | <seg1> <seg2> ...) [-force] [-normalize] [-filter] [-noAdditions]
这个类主要是根据fetcher的输出去更新crawldb。 map和reduce分别做了两方面的事情,在map里是对url的nomalizer,和filte,在reduce里是对新抓取进来的页面(CrawlDatum)和原先已经存在的进行合并。
MapReduce:合并抓取的和分析后的输出到crawldb里
In: <url,CrawlDatum>现有的db加上抓取后的和分析后的输出
Map() is identity
Reduce() 合并所有实体(entry)成一个,以抓取后的状态覆盖原先的db状态信息,统计出分析后的链接数
Out: 新的crawl db
6.LinkDb linkDbTool = new LinkDb(conf); //Maintains an inverted link map, listing incoming links for each url.
Usage: LinkDb <linkdb> (-dir <segmentsDir> | <seg1> <seg2> ...) [-force] [-noNormalize] [-noFilter]
这个类的作用是管理新转化进来的链接映射,并列出每个url的外部链接(incoming links)。先是对每一个url取出它的outLinks,作map操作把这个url作为每个outLinks的incoming link,在reduce里把根据每个key来把一个url的所有incoming link都加到inlinks里。这样就把每个url的外部链接统计出来了。然后一步是对这些新加进来的链接进行合并。
● MapReduce: 统计每个链接的外部链接
In: <url,ParseData>, 包含所有链接的分析后的结果
Map(srcUrl, ParseData> → <destUrl, Inlinks>
为每个链出链接收集一个入链。
Inlinks: <srcUrl, anchorText>*
Reduce()加上外部入链数量
Out: <url, Inlinks>, 一个相关完整的链接地图
7.Indexer indexer = new Indexer(conf); //Create indexes for segments
Usage: <index> <crawldb> <linkdb> <segment> ...
这个类的任务是另一方面的工作了,它是基于hadoop和lucene的分布式索引。它就是为前面爬虫抓取回来的数据进行索引好让用户可以搜索到这些数据。这里的输入就比较多了,有segments下的fetch_dir,parseData和parseText,还有crawldb下的 current_dir和linkdb下的current_dir。在这个类里,map也不做,在reduce时处理。当然要把这些数据体组合成一个 lucene的document让它索引了。在reduce里组装好后收集时是<url,doc>,最后在输出的OutputFormat类里进行真正的索引。
● MapReduce: 生成lucene的索引文件
In: 外个文件, values 以 <Class, Object>包装
<url, ParseData> from parse, 有title, metadata, 等等信息.
<url, ParseText> from parse, 文本 text
<url, Inlinks> from invert, 锚文本anchors
<url, CrawlDatum> from fetch,用于抓取
Map() is identity
Reduce() 生成Lucene Document
调用index插件
Out: 建立Lucene 索引; 最后存储到文件系统上
8. DeleteDuplicates dedup = new DeleteDuplicates(conf); //这个类的作用就是它的名字了。
Usage: DeleteDuplicates <indexes> ...
这个类的作用就是这它的名字所写的意思--去重。前面索引后(当然不是一次时的情况)会有重复,所以要去重。为什么呢,在一次索引时是不重复的,可是多次抓取后就会有重复了。就是这个原因才要去重。当然去重的规则有两种一个是以时间为标准,一种是以内容的md5值为标准。
9.IndexMerger merger = new IndexMerger(conf);
IndexMerger [-workingdir <workingdir>] outputIndex indexesDir...
这个类就比较简单了,把所有的小索引合并成一个索引。在这一步没有用到map-reduce。
在这九大步骤中generator,fetcher,parseSegment,crawlDbTool会根据抓取的层数循环运行,当抓取的层数大于1时会运行linkInvert,index,dedup,和merge。
=================================================================
crawdb,linkdb
是web link目录,存放url 及url的互联关系,作为爬行与重新爬行的依据,页面默认30天过期。
segments
是主目录,存放抓回来的网页。页面内容有bytes[]的raw content 和 parsed text的形式。nutch以广度优先的原则来爬行,因此每爬完一轮会生成一个segment目录。
index
是lucene的索引目录,是indexes目录里所有index合并后的完整索引,注意索引文件只对页面内容进行索引,没有进行存储,因此查询时要去访问segments目录才能获得页面内容。
如 果你研究过Lucene,相信index和indexes目录中的文件会非常熟悉的,他们是索引文件,使用不同扩展名的文件来存储不同的内容,比 如,.nrm文件是存储标准化因子信息的,.fnm文件是存储文件名字信息的,.prx文件是存储Term的词频信息的,等等。
=================================================================
Nutch整体执行流程:
抓取程序自动在用户根目录(/user/nutch)下面建立了crawl10目录,可以看到crawldb,segments,index,indexs,linkdb目录,
1)crawldb目录下面存放下载的URL,以及下载的日期,用来页面更新检查时间。
2)linkdb目录存放URL的关联关系,是下载完成后分析时创建的,通过这个关联关系可以实现类似google的pagerank功能。
3)segments目录存储抓取的页面,下面子目录的个数与获取页面的层数有关系,我指定-depth是10层,这个目录下就有10层。
里面有6个子目录
content,下载页面的内容
crawl_fetch,下载URL的状态内容
crawl_generate,待下载的URL的集合,在generate任务生成时和下载过程中持续分析出来
crawl_parse,存放用来更新crawldb的外部链接库
parse_data,存放每个URL解析出来的外部链接和元数据
parse_text,存放每个解析过的URL的文本内容
4)index目录存放符合lucene格式的索引目录,是indexs里所有的索引内容合并后的完整内容,看了一下这里的索引文件和用lucenedemo做出来的文件名称都不一样,待进一步研究
5)indexs目录存放每次下载的索引目录,存放part-0000到part-0003
====================================================================
抓取程序工作流程
(1.) 建立初始URL集
(2.) 将URL集注入crawldb数据库---inject
这一步骤,上面的图中没有涉及到。既然需要维护一个crawlDB,那么在任何时候只要与抓取任务有关的而且是有用的信息都会被写入crawlDB的
(3.) 根据crawldb数据库创建抓取列表---generate
(4.) 执行抓取,获取网页信息---fetch
(5.) 更新数据库,把获取到的页面信息存入数据库中---updatedb
(6.) 重复进行3~5的步骤,直到预先设定的抓取深度。---这个循环过程被称为“产生/抓取/更新”循环
(7.) 根据sengments的内容更新linkdb数据库---invertlinks
(8.) 建立索引---index
搜索程序工作流程
(1.) 用户通过用户接口进行查询操作
(2.) 将用户查询转化为lucene查询
(3.) 从索引库中提取满足用户检索需求的结果集
(4.) 返回结
===================================================================
/* Perform complete crawling and indexing given a set of root urls. */ public static void main(String args[]) throws Exception { LOG.info("Thank you for using the turbosearch,It was based on Nutch,Thanks for the open source"); LOG.info(" gavin"); if (args.length < 1) { System.out.println ("Usage: Crawl <urlDir> [-dir d] [-threads n] [-depth i] [-topN N]"); return; } Configuration conf = NutchConfiguration.create(); conf.addResource("crawl-tool.xml"); JobConf job = new NutchJob(conf); Path rootUrlDir = null; Path dir = new Path("crawl-" + getDate()); int threads = job.getInt("fetcher.threads.fetch", 10); int depth = 5; long topN = Long.MAX_VALUE; 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 (args[i] != null) { rootUrlDir = new Path(args[i]); } } FileSystem fs = FileSystem.get(job); if (LOG.isInfoEnabled()) { LOG.info("crawl started in: " + dir); LOG.info("rootUrlDir = " + rootUrlDir); LOG.info("threads = " + threads); LOG.info("depth = " + depth); if (topN != Long.MAX_VALUE) LOG.info("topN = " + topN); } Path crawlDb = new Path(dir + "/crawldb"); Path linkDb = new Path(dir + "/linkdb"); Path segments = new Path(dir + "/segments"); Path indexes = new Path(dir + "/indexes"); Path index = new Path(dir + "/index"); Path tmpDir = job.getLocalPath("crawl"+Path.SEPARATOR+getDate()); Injector injector = new Injector(conf); Generator generator = new Generator(conf); Fetcher fetcher = new Fetcher(conf); ParseSegment parseSegment = new ParseSegment(conf); CrawlDb crawlDbTool = new CrawlDb(conf); LinkDb linkDbTool = new LinkDb(conf); Indexer indexer = new Indexer(conf); DeleteDuplicates dedup = new DeleteDuplicates(conf); IndexMerger merger = new IndexMerger(conf); // initialize crawlDb injector.inject(crawlDb, rootUrlDir); int i; for (i = 0; i < depth; i++) { // generate new segment Path segment = generator.generate(crawlDb, segments, -1, topN, System .currentTimeMillis()); if (segment == null) { LOG.info("Stopping at depth=" + i + " - no more URLs to fetch."); break; } fetcher.fetch(segment, threads, org.apache.nutch.fetcher.Fetcher.isParsing(conf)); // fetch it //方法抓取中的核心 JobClient.runJob(job); if (!Fetcher.isParsing(job)) { parseSegment.parse(segment); // parse it, if needed } crawlDbTool.update(crawlDb, new Path[]{segment}, true, true); // update crawldb } if (i > 0) { linkDbTool.invert(linkDb, segments, true, true, false); // invert links if(indexes != null) { // Delete old indexes if (fs.exists(indexes)) { LOG.info("Deleting old indexes: " + indexes); fs.delete(indexes, true); } // Delete old index if (fs.exists(index)) { LOG.info("Deleting old merged index: " + index); fs.delete(index, true); } } // index, dedup & merge FileStatus[] fstats = fs.listStatus(segments, HadoopFSUtil.getPassDirectoriesFilter(fs)); indexer.index(indexes, crawlDb, linkDb, Arrays.asList(HadoopFSUtil.getPaths(fstats))); if(indexes != null) { dedup.dedup(new Path[] { indexes }); fstats = fs.listStatus(indexes, HadoopFSUtil.getPassDirectoriesFilter(fs)); merger.merge(HadoopFSUtil.getPaths(fstats), index, tmpDir); } } else { LOG.warn("No URLs to fetch - check your seed list and URL filters."); } if (LOG.isInfoEnabled()) { LOG.info("crawl finished: " + dir); } }
日志分析:
下面是我用来crawl的命令 > bin/nutch crawl urls -dir crawl10 -depth 10 -threads 10 >& nohup.out crawl started in: crawl10 //表明网目录络蜘蛛的名称 rootUrlDir = urls //待下载数据的列表文件或列表 threads = 10 //下载线程为10个 depth = 10 //深度是10层 Injector: starting //注入下载列表 Injector: crawlDb: crawl10/crawldb Injector: urlDir: urls Injector: Converting injected urls to crawl db entries. //根据注入的列表生成待下载的地址库 Injector: Merging injected urls into crawl db. //执行merge Injector: done Generator: Selecting best-scoring urls due for fetch. //判断网页重要性,决定下载顺序 Generator: starting Generator: segment: crawl10/segments/20080904102201 //生成下载结果存储的数据段 Generator: filtering: false Generator: topN: 2147483647 //没有指定topN大小,nutch会取默认值 Generator: Partitioning selected urls by host, for politeness. //将url下载列表按hadoop的中配置文件slaves中定义的datanode来分配。 Generator: done. Fetcher: starting Fetcher: segment: crawl10/segments/20080904102201 //下载指定网页内容到segment中去 Fetcher: done CrawlDb update: starting //下载完毕后,更新下载数据库,增加新的下载 CrawlDb update: db: crawl10/crawldb CrawlDb update: segments: [crawl10/segments/20080904102201] CrawlDb update: additions allowed: true CrawlDb update: URL normalizing: true CrawlDb update: URL filtering: true CrawlDb update: Merging segment data into db. CrawlDb update: done //循环执行下载 Generator: Selecting best-scoring urls due for fetch. Generator: starting Generator: segment: crawl10/segments/20080904102453 Generator: filtering: false Generator: topN: 2147483647 Generator: Partitioning selected urls by host, for politeness. Generator: done. Fetcher: starting Fetcher: segment: crawl10/segments/20080904102453 Fetcher: done CrawlDb update: starting CrawlDb update: db: crawl10/crawldb CrawlDb update: segments: [crawl10/segments/20080904102453] CrawlDb update: additions allowed: true CrawlDb update: URL normalizing: true CrawlDb update: URL filtering: true CrawlDb update: Merging segment data into db. CrawlDb update: done ...... //一共循环10次,Nutch的局域网模式采用了广度优先策略,把二级页面抓取完成以后,进行三级页面抓取。 LinkDb: starting //进行网页链接关系分析 LinkDb: linkdb: crawl10/linkdb LinkDb: URL normalize: true //规范化 LinkDb: URL filter: true //根据crawl-urlfilter.txt来过滤 LinkDb: adding segment: /user/nutch/crawl10/segments/20080904102201 LinkDb: adding segment: /user/nutch/crawl10/segments/20080904102453 LinkDb: adding segment: /user/nutch/crawl10/segments/20080904102841 LinkDb: adding segment: /user/nutch/crawl10/segments/20080904104322 LinkDb: adding segment: /user/nutch/crawl10/segments/20080904113511 LinkDb: adding segment: /user/nutch/crawl10/segments/20080904132510 LinkDb: adding segment: /user/nutch/crawl10/segments/20080904153615 LinkDb: adding segment: /user/nutch/crawl10/segments/20080904175052 LinkDb: adding segment: /user/nutch/crawl10/segments/20080904194724 LinkDb: adding segment: /user/nutch/crawl10/segments/20080904211956 LinkDb: done //链接分析完毕 Indexer: starting //开始创建索引 Indexer: linkdb: crawl10/linkdb Indexer: adding segment: /user/nutch/crawl10/segments/20080904102201 Indexer: adding segment: /user/nutch/crawl10/segments/20080904102453 Indexer: adding segment: /user/nutch/crawl10/segments/20080904102841 Indexer: adding segment: /user/nutch/crawl10/segments/20080904104322 Indexer: adding segment: /user/nutch/crawl10/segments/20080904113511 Indexer: adding segment: /user/nutch/crawl10/segments/20080904132510 Indexer: adding segment: /user/nutch/crawl10/segments/20080904153615 Indexer: adding segment: /user/nutch/crawl10/segments/20080904175052 Indexer: adding segment: /user/nutch/crawl10/segments/20080904194724 Indexer: adding segment: /user/nutch/crawl10/segments/20080904211956 Indexer: done //索引创建完毕 Dedup: starting //索页去重 Dedup: adding indexes in: crawl10/indexes Dedup: done merging indexes to: crawl10/index //索引合并 Adding /user/nutch/crawl10/indexes/part-00000 Adding /user/nutch/crawl10/indexes/part-00001 Adding /user/nutch/crawl10/indexes/part-00002 Adding /user/nutch/crawl10/indexes/part-00003 done merging //合并完毕 crawl finished: crawl10 //入口注入、循环下载、链接分析、建立索引、去重、合并
发表评论
-
如何做好垂直搜索
2009-10-03 20:28 1044垂直搜索技术主要分为 ... -
hadoop的eclipse开发豪华文章
2009-09-28 21:57 1599hadoop的eclipse开发豪华文章:http://ebi ... -
Hadoop分析
2009-09-27 10:10 1125好链接:http://www.kuqin ... -
Nutch插件机制
2009-09-26 20:41 1296Plugin插件机制为Nutch提 ... -
nutch防止中文乱码
2009-09-19 13:59 959<Connector port="8080&q ... -
Nutch中MapReduce的分析
2009-09-17 21:42 1115作者:马士华 发表于:2008-03-06 20:11 最后更 ... -
Nutch1.0源码分析-----抓取部分
2009-09-17 21:33 970链接地址:http://blog.csdn.net/ninju ... -
nutch1.0各种命令
2009-09-17 20:53 1138nutch.job 文件的使用: hadoop jar nu ... -
常用网址
2009-09-16 22:08 920吴楚狂生 nutch 总结:http://blog.csdn. ... -
Nutch插件机制和Nutch一个插件实例
2009-09-16 21:20 1568通过这篇文章:),终于懂得了nutch插件啦:),Thanks ... -
Run Nutch In Eclipse on Linux and Windows nutch version 1.0
2009-09-16 21:12 3957参考官方文档,通过努力终于我nutch在eclispe下跑通了 ...
相关推荐
Nutch1.0的API,不过注意没有搜索功能
在这个特定的“Nutch1.0修改版”中,开发者已经对原始代码进行了调整,以整合中文分词功能。这使得Nutch能够更有效地处理中文网页的抓取和索引,从而在中文搜索引擎应用中发挥更大的作用。 中文分词是中文信息处理...
Nutch 是一个开源的、Java 实现的搜索引擎。它提供了我们运行自己的搜索引擎所需的全部工具。
Nutch 是一个开源Java 实现的搜索引擎。它提供了我们运行自己的搜索引擎所需的全部工具。包括全文搜索和Web爬虫。
Nutch 是一个开源Java 实现的搜索引擎。它提供了我们运行自己的搜索引擎所需的全部工具。包括全文搜索和Web爬虫。
Nutch 是一个开源Java 实现的搜索引擎。它提供了我们运行自己的搜索引擎所需的全部工具。包括全文搜索和Web爬虫。
接下来,需从官方网站下载Nutch-1.0的源代码压缩包(`nutch-1.0.tar.gz`),并进行解压。随后,在Eclipse中创建一个新的Java项目,命名可自定义,如“Nutch”,并在创建过程中选择“从现有源代码创建项目”选项,...
在Nutch的爬取过程中,每次`nutch crawl`操作都会生成一个新的目录,包含爬取的网页数据、链接数据库(linkdb)、网页数据库(crawldb)和索引文件。当需要将多次爬取的结果合并成一个统一的数据库时,可以使用`...
通过理解和分析 `Crawl` 类的源码,开发者可以更好地掌握 Nutch 如何处理输入,以及如何根据这些输入配置和执行复杂的网络抓取任务。对于想要深入了解 Nutch 或者想要定制 Nutch 功能的人来说,研究 `Crawl` 类的...
Nutch 是一个开源的、Java 实现的搜索引擎。它提供了我们运行自己的搜索引擎所需的全部工具。 nutch 1.0
Nutch 是一个开源Java 实现的搜索引擎。它提供了我们运行自己的搜索引擎所需的全部工具。包括全文搜索和Web爬虫。
Nutch 是一个开源的、Java 实现的搜索引擎。它提供了我们运行自己的搜索引擎所需的全部工具。 nutch 1.0
Nutch 是一个开源的、Java 实现的搜索引擎。它提供了我们运行自己的搜索引擎所需的全部工具。 nutch 1.0
nutch-1.0-dev.jar nutch devlope
Nutch-1.0分布式安装手册是一份详细指导如何在多台计算机上部署和配置Apache Nutch的文档。Apache Nutch是一款开源的网络爬虫软件,用于抓取互联网上的网页并进行索引,是大数据领域中搜索引擎构建的重要工具。这份...
Nutch的源代码包含了整个项目的完整实现,包括爬虫、索引器、搜索器以及相关的配置和文档。这对于开发者和研究者来说是一个宝贵的资源,他们可以深入理解搜索引擎的工作原理,学习如何处理大规模的网络数据,或者对...
接下来,你需要从 Apache 官方站点或指定的 mirror 下载 Nutch 1.0 的源代码包。你可以访问 http://apache.freelamp.com/lucene/nutch/ 并下载 nutch-1.0.tar.gz 文件,然后将其解压缩。 在 Eclipse 中,创建一个新...
总的来说,"nutch 爬到的 CSDN 数据"是一个关于利用开源爬虫工具 Nutch 抓取并分析 CSDN 网站内容的过程,这个过程涉及到网络爬虫技术、数据抓取策略、数据分析等多个方面,具有广泛的应用前景和技术价值。...
Nutch 是一个开源Java 实现的搜索引擎。它提供了我们运行自己的搜索引擎所需的全部工具。包括全文搜索和Web爬虫。
### 在Eclipse中调试Nutch 1.0 #### 概述 本文旨在提供一个详细的指南,帮助用户在Eclipse IDE环境下配置并调试Nutch 1.0版本。Nutch是一款开源的网络爬虫框架,它能够抓取、索引互联网上的网页,并支持多种插件...