- 浏览: 1653701 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (405)
- C/C++ (16)
- Linux (60)
- Algorithm (41)
- ACM (8)
- Ruby (39)
- Ruby on Rails (6)
- FP (2)
- Java SE (39)
- Java EE (6)
- Spring (11)
- Hibernate (1)
- Struts (1)
- Ajax (5)
- php (2)
- Data/Web Mining (20)
- Search Engine (19)
- NLP (2)
- Machine Learning (23)
- R (0)
- Database (10)
- Data Structure (6)
- Design Pattern (16)
- Hadoop (2)
- Browser (0)
- Firefox plugin/XPCOM (8)
- Eclise development (5)
- Architecture (1)
- Server (1)
- Cache (6)
- Code Generation (3)
- Open Source Tool (5)
- Develope Tools (5)
- 读书笔记 (7)
- 备忘 (4)
- 情感 (4)
- Others (20)
- python (0)
最新评论
-
532870393:
请问下,这本书是基于Hadoop1还是Hadoop2?
Hadoop in Action简单笔记(一) -
dongbiying:
不懂呀。。
十大常用数据结构 -
bing_it:
...
使用Spring MVC HandlerExceptionResolver处理异常 -
一别梦心:
按照上面的执行,文件确实是更新了,但是还是找不到kernel, ...
virtualbox 4.08安装虚机Ubuntu11.04增强功能失败解决方法 -
dsjt:
楼主spring 什么版本,我的3.1 ,xml中配置 < ...
使用Spring MVC HandlerExceptionResolver处理异常
今天来看看Nutch如何Parse网页的:
Nutch使用了两种Html parser工具(NekoHTML和TagSoup)来实现html的提取,这两种工具是可通过配置来选择的。
当然你要自己实现Parser你还可以选择HTMLParser[基于visitor访问者模式同时也提供了Event driver的接口]来
提取网页。如果你用惯了XML一套处理方法,使用NekoHTML和TagSoup应该会比较顺手的。
我们来看看类public class HtmlParser implements Parser的实现:
首先为了更好的理解下面的代码先看看成员变量:
CHUNK_SIZE提取html meta tag部分的html片断的长度,一般meta tag没有超过2000bytes的,所以只需要从这部分
提取就行了
metaPattern为meta tag匹的正则模式
charsetPattern为字符集编码的正则模式
parserImpl是具体使用的是NekoHTML还是TagSoup来parser html.如果parserImpl为"tagsoup"就使用TagSoup,否则就使用NekoHTML。
用来从html在meta tag里面提取出charset或Content-Type中指定的编码:
length限定在meta tag部分提取,通过正则表达式很容易提取出编码
最重要的一个方法是:
public Parse getParse(Content content)
这个方法返回了包含了提取所有结果Parse对象:
这个方法写的比较长,近100行,其实整个方法可以分解成几个小方法:
提取base url,提取encoding,根据提取出的编码提取content,提取meta tags,提取outlinks,最后根据提取得到的
text和parseDate构造Parse对象
下面我们一个一个看:
提取base url
提取encoding:
设置好编码方式,从content中提取DocumentFragment
提取meta tag,并检查meta指令
提取出outlinks:
构建parse对象:
下面这个方法根据parserImpl字段,使用NekoHTML或TagSoup来提取content得到DocumentFragment对象
网页抓取部分到此基本结束,必要的部分相应再作补充。等研究好google的map-reduce再继续其他部分。
1、可以通过bin/nutch readseg查看,或者通过nutch提供的API,具体格式可以参考:http://wiki.apache.org/nutch/NutchFileFormats
2、主要是防止被封,多设置一些代理的ip
3、可以直接用Lucene或者Solr。
Nutch使用了两种Html parser工具(NekoHTML和TagSoup)来实现html的提取,这两种工具是可通过配置来选择的。
当然你要自己实现Parser你还可以选择HTMLParser[基于visitor访问者模式同时也提供了Event driver的接口]来
提取网页。如果你用惯了XML一套处理方法,使用NekoHTML和TagSoup应该会比较顺手的。
我们来看看类public class HtmlParser implements Parser的实现:
首先为了更好的理解下面的代码先看看成员变量:
private static final int CHUNK_SIZE = 2000; private static Pattern metaPattern = Pattern.compile("<meta\\s+([^>]*http-equiv=\"?content-type\"?[^>]*)>", Pattern.CASE_INSENSITIVE); private static Pattern charsetPattern = Pattern.compile("charset=\\s*([a-z][_\\-0-9a-z]*)", Pattern.CASE_INSENSITIVE); private String parserImpl;
CHUNK_SIZE提取html meta tag部分的html片断的长度,一般meta tag没有超过2000bytes的,所以只需要从这部分
提取就行了
metaPattern为meta tag匹的正则模式
charsetPattern为字符集编码的正则模式
parserImpl是具体使用的是NekoHTML还是TagSoup来parser html.如果parserImpl为"tagsoup"就使用TagSoup,否则就使用NekoHTML。
用来从html在meta tag里面提取出charset或Content-Type中指定的编码:
length限定在meta tag部分提取,通过正则表达式很容易提取出编码
private static String sniffCharacterEncoding(byte[] content) { int length = content.length < CHUNK_SIZE ? content.length : CHUNK_SIZE; // We don't care about non-ASCII parts so that it's sufficient // to just inflate each byte to a 16-bit value by padding. // For instance, the sequence {0x41, 0x82, 0xb7} will be turned into // {U+0041, U+0082, U+00B7}. String str = new String(content, 0, 0, length); Matcher metaMatcher = metaPattern.matcher(str); String encoding = null; if (metaMatcher.find()) { Matcher charsetMatcher = charsetPattern.matcher(metaMatcher.group(1)); if (charsetMatcher.find()) encoding = new String(charsetMatcher.group(1)); } return encoding; }
最重要的一个方法是:
public Parse getParse(Content content)
这个方法返回了包含了提取所有结果Parse对象:
这个方法写的比较长,近100行,其实整个方法可以分解成几个小方法:
提取base url,提取encoding,根据提取出的编码提取content,提取meta tags,提取outlinks,最后根据提取得到的
text和parseDate构造Parse对象
下面我们一个一个看:
提取base url
URL base; try { base = new URL(content.getBaseUrl()); } catch (MalformedURLException e) { return new ParseStatus(e).getEmptyParse(getConf()); }
提取encoding:
//直接从content中的metadata中提取 byte[] contentInOctets = content.getContent(); InputSource input = new InputSource(new ByteArrayInputStream(contentInOctets)); String contentType = content.getMetadata().get(Response.CONTENT_TYPE); String encoding = StringUtil.parseCharacterEncoding(contentType); if ((encoding != null) && !("".equals(encoding))) { metadata.set(Metadata.ORIGINAL_CHAR_ENCODING, encoding); if ((encoding = StringUtil.resolveEncodingAlias(encoding)) != null) { metadata.set(Metadata.CHAR_ENCODING_FOR_CONVERSION, encoding); if (LOG.isTraceEnabled()) { LOG.trace(base + ": setting encoding to " + encoding); } } } //如果从metadata中没有提取到,使用前面sniffCharacterEncoding从meta tag提取 // sniff out 'charset' value from the beginning of a document if ((encoding == null) || ("".equals(encoding))) { encoding = sniffCharacterEncoding(contentInOctets); if (encoding!=null) { metadata.set(Metadata.ORIGINAL_CHAR_ENCODING, encoding); if ((encoding = StringUtil.resolveEncodingAlias(encoding)) != null) { metadata.set(Metadata.CHAR_ENCODING_FOR_CONVERSION, encoding); if (LOG.isTraceEnabled()) { LOG.trace(base + ": setting encoding to " + encoding); } } } } //如果还没有提取到,使用默认的编码 if (encoding == null) { // fallback encoding. // FIXME : In addition to the global fallback value, // we should make it possible to specify fallback encodings for each ccTLD. // (e.g. se: windows-1252, kr: x-windows-949, cn: gb18030, tw: big5 // doesn't work for jp because euc-jp and shift_jis have about the // same share) encoding = defaultCharEncoding; metadata.set(Metadata.CHAR_ENCODING_FOR_CONVERSION, defaultCharEncoding); if (LOG.isTraceEnabled()) { LOG.trace(base + ": falling back to " + defaultCharEncoding); } }
设置好编码方式,从content中提取DocumentFragment
input.setEncoding(encoding); if (LOG.isTraceEnabled()) { LOG.trace("Parsing..."); } root = parse(input); } catch (IOException e) { return new ParseStatus(e).getEmptyParse(getConf()); } catch (DOMException e) { return new ParseStatus(e).getEmptyParse(getConf()); } catch (SAXException e) { return new ParseStatus(e).getEmptyParse(getConf()); } catch (Exception e) { e.printStackTrace(LogUtil.getWarnStream(LOG)); return new ParseStatus(e).getEmptyParse(getConf()); }
提取meta tag,并检查meta指令
HTMLMetaProcessor.getMetaTags(metaTags, root, base); if (LOG.isTraceEnabled()) { LOG.trace("Meta tags for " + base + ": " + metaTags.toString()); } // check meta directives if (!metaTags.getNoIndex()) { // okay to index StringBuffer sb = new StringBuffer(); if (LOG.isTraceEnabled()) { LOG.trace("Getting text..."); } utils.getText(sb, root); // extract text text = sb.toString(); sb.setLength(0); if (LOG.isTraceEnabled()) { LOG.trace("Getting title..."); } utils.getTitle(sb, root); // extract title title = sb.toString().trim(); }
提取出outlinks:
if (!metaTags.getNoFollow()) { // okay to follow links ArrayList l = new ArrayList(); // extract outlinks URL baseTag = utils.getBase(root); if (LOG.isTraceEnabled()) { LOG.trace("Getting links..."); } utils.getOutlinks(baseTag!=null?baseTag:base, l, root); outlinks = (Outlink[])l.toArray(new Outlink[l.size()]); if (LOG.isTraceEnabled()) { LOG.trace("found "+outlinks.length+" outlinks in "+content.getUrl()); } }
构建parse对象:
ParseStatus status = new ParseStatus(ParseStatus.SUCCESS); if (metaTags.getRefresh()) { status.setMinorCode(ParseStatus.SUCCESS_REDIRECT); status.setMessage(metaTags.getRefreshHref().toString()); } ParseData parseData = new ParseData(status, title, outlinks, content.getMetadata(), metadata); parseData.setConf(this.conf); Parse parse = new ParseImpl(text, parseData); // run filters on parse parse = this.htmlParseFilters.filter(content, parse, metaTags, root); if (metaTags.getNoCache()) { // not okay to cache parse.getData().getParseMeta().set(Nutch.CACHING_FORBIDDEN_KEY, cachingPolicy); }
下面这个方法根据parserImpl字段,使用NekoHTML或TagSoup来提取content得到DocumentFragment对象
private DocumentFragment parse(InputSource input) throws Exception { if (parserImpl.equalsIgnoreCase("tagsoup")) return parseTagSoup(input); else return parseNeko(input); }
网页抓取部分到此基本结束,必要的部分相应再作补充。等研究好google的map-reduce再继续其他部分。
评论
3 楼
xieyijiejie
2014-04-17
你好,我的nutch2.2.1项目在调试的时候怎么没走htmlparser呀,但是存储到数据库的数据中text是有的,觉得很奇怪呀,我还在htmlparser中设置了断点
2 楼
fuliang
2013-08-26
koubi1986 写道
你好!请教一些问题:
请问一下
1。你是如何把nutch抓取到的二进制内容,在项目中读取的。
2。nutch抓取时候,发现有很多url没有被成功抓取过来,请问你做的时候,有什么 办法是提高成功率。
3。对抓取过来内容你们是如何进行关键词搜索
希望群主可以帮忙解答一下。万分感激!
email:83132614@qq.com
请问一下
1。你是如何把nutch抓取到的二进制内容,在项目中读取的。
2。nutch抓取时候,发现有很多url没有被成功抓取过来,请问你做的时候,有什么 办法是提高成功率。
3。对抓取过来内容你们是如何进行关键词搜索
希望群主可以帮忙解答一下。万分感激!
email:83132614@qq.com
1、可以通过bin/nutch readseg查看,或者通过nutch提供的API,具体格式可以参考:http://wiki.apache.org/nutch/NutchFileFormats
2、主要是防止被封,多设置一些代理的ip
3、可以直接用Lucene或者Solr。
1 楼
koubi1986
2013-08-20
你好!请教一些问题:
请问一下
1。你是如何把nutch抓取到的二进制内容,在项目中读取的。
2。nutch抓取时候,发现有很多url没有被成功抓取过来,请问你做的时候,有什么 办法是提高成功率。
3。对抓取过来内容你们是如何进行关键词搜索
希望群主可以帮忙解答一下。万分感激!
email:83132614@qq.com
请问一下
1。你是如何把nutch抓取到的二进制内容,在项目中读取的。
2。nutch抓取时候,发现有很多url没有被成功抓取过来,请问你做的时候,有什么 办法是提高成功率。
3。对抓取过来内容你们是如何进行关键词搜索
希望群主可以帮忙解答一下。万分感激!
email:83132614@qq.com
发表评论
-
Lucene 索引格式
2013-06-25 20:11 0索引结构: 索引层次 ... -
计算广告学
2012-08-12 13:53 0计算广告学一: 1、核 ... -
《Lucene in Action》简单笔记
2011-12-22 09:19 0第一章 Meet Lucene -
Information Retrieval Resources
2011-04-07 16:40 1388Information Retrieval Resource ... -
使用Jsoup抽取数据
2011-03-20 19:22 4946Jsoup是一个Java的HTML解析器,提供了非常方便的抽取 ... -
常见文件类型识别
2010-09-22 20:09 11880根据文件的后缀名识别文件类型并不准确,可以使用文件的头信息进行 ... -
(zz)信息检索领域资料整理
2010-06-05 13:05 3171A Guide to Information Retrieva ... -
Introduce to Inforamtion Retrieval读书笔记(2)
2009-10-31 13:02 1935The term vocabulary and posting ... -
Introduce to Inforamtion Retrieval读书笔记(1)
2009-10-25 23:49 2053很好的一本书,介绍的非常全面,看了很久了,还没有看完,刚看完前 ... -
Query Log Mining notes
2009-10-02 18:08 1272Enhancing Efficiency of Search ... -
百度搜索的一些高级语法
2009-08-27 20:06 19321.title语法 就是在title ... -
Hadoop好书推荐:Hadoop The Definitive Guide
2009-08-16 22:49 3640第一本详细介绍Hadoop的书籍,从网上下来看了几章,作者是H ... -
Java开源搜索引擎[收藏]
2008-04-24 00:09 2903Egothor Egothor是一个用Java编写的开 ... -
分享一本斯坦福的信息检索的教材
2008-01-04 23:59 2463斯坦福的信息检索的教材,还没出版,先分享一下电子版原稿. 对于 ... -
分享一本搜索引擎的电子书
2007-12-29 19:42 2530还没有来得及看,但搜索引擎的书不是很好找,先放上,希望对大家能 ... -
分享一个Nutch入门学习的资料
2007-12-18 20:49 4267分享一个Nutch入门学习的资料,感觉写的还不错. -
[转]MAP/REDUCE:Google和Nutch实现异同及其他
2007-12-15 19:21 2998设计要素 nutch包含以下几个部分: 辅助类 Log:记载运 ... -
Nutch源代码学习小小总结一下
2007-12-15 19:13 4468我现在看得源码主要是网页抓取部分,这部分相对比较容易。我首先定 ... -
搜索引擎Nutch源代码研究之一 网页抓取(3)
2007-12-15 16:39 4587今天我们看看Nutch网页抓取,所用的几种数据结构: 主要涉及 ... -
搜索引擎Nutch源代码研究之一 网页抓取(2)
2007-12-15 00:36 5565今天我们来看看Nutch的源代码中的protocol-h ...
相关推荐
从Apache官方网站下载Nutch的最新源代码,通常通过Git克隆仓库。解压后,进入Nutch的工作目录。 3. **配置Nutch** 打开`conf/nutch-site.xml`文件,这是Nutch的主要配置文件。以下是一些关键配置项: - `...
2. **Nutch源代码**:包括Nutch的爬虫模块、索引模块和搜索模块,可以帮助开发者学习如何配置和运行一个完整的网络爬虫,以及如何与Lucene集成进行全文检索。 3. **示例项目**:可能包含了一些示例应用,展示如何...
Nutch不仅仅是一个搜索引擎,它还包含了一个Web爬虫,能够抓取互联网上的网页,并对抓取的数据进行索引和处理。 Nutch的源代码包含了整个项目的完整实现,包括爬虫、索引器、搜索器以及相关的配置和文档。这对于...
Nutch 的源代码解析对于深入理解搜索引擎的工作原理以及自定义搜索引擎的实现非常有帮助。下面我们将详细探讨 Nutch 的注入(Injector)过程,这是整个爬取流程的第一步。 Injector 类在 Nutch 中的作用是将输入的 ...
总的来说,王学松的“Lucene+Nutch搜索引擎开发实例代码”是一份宝贵的教育资源,它可以帮助开发者快速入门搜索引擎开发,并深入了解这两个项目的内部工作机制。通过实践这些代码,不仅可以提升技术能力,还能为构建...
分布式搜索引擎Nutch开发详解 Nutch是一款开源的、基于Java实现的全文搜索引擎,它主要用于构建大规模的网络爬虫系统,并提供了对抓取的网页进行索引和搜索的功能。Nutch与Hadoop紧密集成,能够充分利用分布式计算...
《lucene+nutch搜索引擎开发源码1》是一个包含开源搜索引擎项目Lucene和Nutch源代码的压缩包,主要针对搜索引擎开发的学习和实践。这个压缩包是书籍《lucene+nutch搜索引擎开发》的一部分,由于源码量较大,因此分为...
《lucene+nutch开发自己的搜索引擎一书源代码》是一份专为初学者设计的资源,旨在教授如何利用Apache Lucene和Nutch构建自定义搜索引擎。Lucene是Java编写的一个高性能全文检索库,而Nutch则是一个开源的网络爬虫...
Nutch 1.5 是一个基于Java开发的开源搜索引擎项目,它主要负责网络抓取、索引和搜索等功能。这个源代码包包含了实现这些功能的所有模块和组件,为开发者提供了深入理解搜索引擎工作原理以及定制化搜索引擎的机会。接...
Nutch是Apache软件基金会的一个开源项目,主要用于构建网络搜索引擎。这个开发资料压缩包包含了与Nutch相关的源代码和可能的配置文件,可以帮助开发者深入了解和学习Nutch的工作原理以及如何进行定制化开发。以下是...
Lucene 是一个全文搜索引擎库,而 Nutch 是一个完整的网络爬虫项目,两者结合可以提供从网页抓取到索引、搜索的一站式解决方案。 在开发自定义搜索引擎的过程中,首先我们需要了解 **Lucene** 的基本原理。Lucene ...
1. **Java编程基础**:由于Nutch是用Java编写的,因此理解和修改Nutch源代码需要扎实的Java基础知识。 2. **搜索引擎原理**:理解搜索引擎的基本工作流程,包括爬虫、预处理、索引和查询处理。 3. **Hadoop和...
2. **Nutch**: Nutch是一个开放源代码的网络爬虫,主要用于抓取和索引网页内容。它基于Lucene,提供了完整的爬虫解决方案,包括网页抓取、预处理(如HTML解析、链接分析、去重等)、索引和搜索功能。Nutch的主要优势...
《Lucene+Nutch搜索引擎开发》是一本专注于搜索引擎技术的书籍,配套光盘资源为学习者提供了丰富的实践材料,尤其对于想要深入理解Nutch搜索引擎开发的读者来说,这是一份不可多得的学习资料。Nutch是基于Apache ...
Nutch 是一个开源的搜索引擎项目,它提供了网络爬虫、索引和搜索的功能。在构建一个自定义的搜索引擎时,可能会遇到几个常见的问题,如搜索结果的关键词高亮、快照链接无效以及网页在预览时的变形。下面将详细讨论...
总之,Nutch是一个强大的开源搜索引擎工具,它不仅适用于构建自己的搜索引擎,也是研究和学习搜索引擎技术的理想平台。通过熟悉其工作流程、分析源代码以及查阅相关文档,你将能够掌握搜索引擎的核心技术和实现细节...
Apache Nutch 是一款高度可扩展的开源全文搜索引擎框架,它为构建自定义的网络爬虫和搜索引擎提供了强大的工具集。Nutch 的设计目标是处理大量网页数据,进行高效的抓取、索引和搜索操作。在“apache-nutch-1.4-src....
- **配置 Nutch 创建索引**:下载 Nutch 的源代码并解压,然后通过 Maven 进行编译。配置 Nutch 的 `conf/nutch-site.xml` 文件以设置存储路径、抓取策略等参数。 - **安装 Tomcat**:Tomcat 用于运行 Nutch 的 UI...
在使用Nutch之前,你需要配置Nutch的运行环境,包括安装Java、设置Hadoop(如果需要分布式爬取)、下载和编译Nutch源代码。还需要配置Nutch的`conf/nutch-site.xml`文件,指定抓取策略、存储路径、爬虫范围等参数。 ...