自己动手写搜索引擎(常搜吧历程七#解析文档之HTML#)(Java、Lucene、hadoop)
一、垂直搜索介绍
1、垂直搜索--即需要抓去大量的网页,分析其中的数据。垂直搜索更着重于正文内容模式分离,数据调整,相关链接分析,是一种结构化分析过程。
2、垂直搜索技术主要分为两个层次:模版级和网页库级
3、模版级是针对网页进行模版设定或者自动生成模版的方式抽取数据,对网页的采集也是针对性的采集,适合规模比较小、信息源少且稳定的需求,优点是快速实施、成本低、灵活性强,缺点是后期维护成本高,信息源和信息量小。
4、网页库级和模版方式最大的区别是对具体网页不依赖,可针对任意正常的网页信息采集信息抽取。缺点是其灵活性差、成本高。
垂直搜索大致需要以下技术:
1、信息采集技术
2、网页信息抽取技术
3、信息的处理技术(重复识别、聚类、比较、分析等)
4、语意相关性分析
5、分词
6、索引
二、使用HttpClient采集页面
1、HTTPClient项目就是专门设计来简化HTTP客户端与服务器进行各种通讯编程。
2、HTTPClient是基于HttpCore实现的一个HTTP/1.1兼容HTTP客户端,它提供了一系列可重用的客户端身份验证、HTTP状态保持、HTTP链接管理module。功能丰富的HTTPClient同时兼具出色的可拓展性和健壮性,目前已经成为了最为流行的JavaHttp客户端组件,为开发Web浏览器、WebService客户端提供了很大的便利。
下载地址: http://hc.apache.org/downloads.cgi
使用HttpClient
一般情况下,使用HttpClient需要以下5个步骤:
1、创建HttpClient的实例
2、创建某种连接方法的实例,在这里是最常见的是Get和Post
3、调用第一步中创建好的HttpClient实例的execute方法,得到执行结果
4、释放连接
5、对得到后的内容进行处理
下面来看两个抓去网页的实例
1、抓取搜索后的页面然后保存
package com.qianyan.test;import org.htmlparser.Node;import org.htmlparser.NodeFilter;import org.htmlparser.Parser;import org.htmlparser.Tag;import org.htmlparser.filters.NodeClassFilter;import org.htmlparser.filters.OrFilter;import org.htmlparser.filters.TagNameFilter;import org.htmlparser.tags.ImageTag;import org.htmlparser.tags.InputTag;import org.htmlparser.tags.LinkTag;import org.htmlparser.tags.OptionTag;import org.htmlparser.tags.SelectTag;import org.htmlparser.util.NodeList;import org.htmlparser.util.ParserException;import org.htmlparser.visitors.NodeVisitor;import org.htmlparser.visitors.ObjectFindingVisitor;import org.junit.Ignore;import org.junit.Test;public class TestHtmlParser {/** * 测试ObjectFindVisitor的用法 */@Test//@Ignorepublic void testImageVistor() {try {ImageTag imgLink;ObjectFindingVisitor visitor = new ObjectFindingVisitor(ImageTag.class);Parser parser = new Parser();parser.setURL("http://www.baidu.com");parser.setEncoding(parser.getEncoding());parser.visitAllNodesWith(visitor);Node[] nodes = visitor.getTags();for (int i = 0; i < nodes.length; i++) {imgLink = (ImageTag) nodes[i];StringBuilder sb = new StringBuilder();sb.append(" ImageURL = " + imgLink.getImageURL());sb.append("---- ImageLocation = " + imgLink.extractImageLocn());sb.append("--- SRC = " + imgLink.getAttribute("SRC"));System.out.println(sb.toString());}} catch (Exception e) {e.printStackTrace();}}/** * 测试NodeVisitor的用法,遍历所有节点 */@Test@Ignorepublic void testVisitorAll() {try {Parser parser = new Parser();parser.setURL("http://www.baidu.com");parser.setEncoding(parser.getEncoding());NodeVisitor visitor = new MyNodeVisitor();parser.visitAllNodesWith(visitor);} catch (ParserException e) {e.printStackTrace();}}/** * 测试NodeClassFilter用法 */@Test@Ignorepublic void testLinkTag(){try{NodeFilter filter = new NodeClassFilter(LinkTag.class);Parser parser = new Parser();parser.setURL("http://www.baidu.com");parser.setEncoding(parser.getEncoding());NodeList list = parser.extractAllNodesThatMatch(filter);for(int i = 0; i < list.size(); i++){LinkTag node = (LinkTag) list.elementAt(i);System.out.println("Link is :" + node.extractLink());}}catch(Exception e){e.printStackTrace();}}/** * 测试TagNameFilter用法 */@Test@Ignorepublic void testNodeFilter(){try{NodeFilter filter = new TagNameFilter("IMG");Parser parser = new Parser();parser.setURL("http://www.baidu.com");parser.setEncoding(parser.getEncoding());NodeList list = parser.extractAllNodesThatMatch(filter);for(int i = 0; i < list.size(); i++){System.out.println(" " + list.elementAt(i).toHtml());}}catch(Exception e){e.printStackTrace();}}/** * 测试OrFilter的用法 */@Test@Ignorepublic void testOrFliter(){NodeFilter inputFilter = new NodeClassFilter(InputTag.class);NodeFilter selectFilter = new NodeClassFilter(SelectTag.class);NodeList nodeList = null;try{Parser parser = new Parser();parser.setInputHTML("<head><title>OrFilter Test</title>" + "<link href=http://www.baidu.com/test01/css.css’ text=’text/css’ rel=’stylesheet’ />" + "<link href=http://www.baidu.com/test02/css.css’ text=’text/css’ rel=’stylesheet’ />" + "</head>" + "<body>" + "<input type=’text’ value=’text1′ name=’text1′/>" + "<input type=’text’ value=’text2′ name=’text2′/>" + "<select><option id=’1′>1</option><option id=’2′>2</option><option id=’3′>3</option></select>" + "<a href='http://www.baidu.com/'>baidu.com</a>" + "</body>");parser.setEncoding(parser.getEncoding());OrFilter lastFilter = new OrFilter();lastFilter.setPredicates(new NodeFilter[]{selectFilter, inputFilter});nodeList = parser.parse(lastFilter);for(int i = 0; i <= nodeList.size(); i++){if(nodeList.elementAt(i) instanceof InputTag){InputTag tag = (InputTag)nodeList.elementAt(i);System.out.println("OrFilter tag name is :" + tag.getTagName()+ " ,tag value is:" + tag.getAttribute("value"));}if(nodeList.elementAt(i) instanceof SelectTag){SelectTag tag = (SelectTag)nodeList.elementAt(i);NodeList list = tag.getChildren();for(int j = 0; j < list.size(); j++){OptionTag option = (OptionTag)list.elementAt(j);System.out.println("OrFilter Option"+ option.getOptionText());}}}}catch(Exception e){e.printStackTrace();}}}/** * 内部实现了NodeVisitor下的visitTag方法 * @author Administrator * */class MyNodeVisitor extends NodeVisitor {public void visitTag(Tag tag) {System.out.println("Tag name is :" + tag.getTagName()+ "--- Class is :" + tag.getClass() + "---"+ tag.getText());}}