Java解析 HTML

来源:互联网 发布:js window.setinterval 编辑:程序博客网 时间:2024/05/21 09:26

一、垂直搜索介绍

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 java.io.BufferedReader;  import java.io.File;  import java.io.FileWriter;  import java.io.IOException;  import java.io.InputStream;  import java.io.InputStreamReader;    import org.apache.http.HttpEntity;  import org.apache.http.HttpResponse;  import org.apache.http.client.ClientProtocolException;  import org.apache.http.client.HttpClient;  import org.apache.http.client.methods.HttpGet;  import org.apache.http.impl.client.DefaultHttpClient;    public class TestHttpClient {        public static void main(String[] args) throws ClientProtocolException, IOException {          HttpClient httpClient = new DefaultHttpClient();          HttpGet httpGet = new HttpGet("http://www.baidu.com/s?wd=java");          HttpResponse response = httpClient.execute(httpGet);          HttpEntity entity = response.getEntity();            InputStream ins = entity.getContent();          BufferedReader reader = new BufferedReader(new InputStreamReader(ins));          FileWriter writer = new FileWriter(new File("E:/baidu.htm"));            String strLine = reader.readLine();          while (null != strLine) {              writer.write(strLine);              strLine = reader.readLine();          }          writer.close();          ins.close();          reader.close();          httpClient.getConnectionManager().shutdown();          System.out.println("网页生成完毕!");      }  }


1、抓取搜索后的页面打印出来

package com.qianyan.test;    import org.apache.http.HttpEntity;  import org.apache.http.HttpResponse;  import org.apache.http.client.HttpClient;  import org.apache.http.client.methods.HttpGet;  import org.apache.http.impl.client.DefaultHttpClient;  import org.apache.http.util.EntityUtils;    public class TestHttpClient2 {        public static void main(String[] args) {          HttpClient httpClient = new DefaultHttpClient();            try {                                //创建HttpGet                HttpGet httpGet = new HttpGet("http://www.ifeng.com");                System.err.println("executing request " + httpGet.getURI());                //执行get请求                HttpResponse response = httpClient.execute(httpGet);                //获取响应实体                HttpEntity entity = response.getEntity();                System.err.println("======================================================");                //打印响应状态                System.out.println(response.getStatusLine());                if (entity != null) {                    //打印响应内容的长度                                System.out.println("Response content lenght:"                            + entity.getContentLength());                    String content = EntityUtils.toString(entity);                                        //解决HttpClient获取中文乱码 ,用String对象进行转码                    System.out.println("Response content:"                            + new String(content.getBytes("ISO-8859-1"),"UTF-8"));                }                System.err.println("==========================================================");            } catch (Exception e) {                // TODO: handle exception            }finally{                //关闭连接,释放资源                httpClient.getConnectionManager().shutdown();            }        }  }  


三、使用JTidy

1、Tidy是W3C用来解析网页的一个软件包,可以方便地将HTML文档转化为符合XML标准的文档,由于XML可以方便地使用XSLT技术对内容进行抽取,所以使用Tidy配合XSLT可以方便地将各种网页的内容抽取出来,保存成我们需要的格式。

2、通过JTidy可以方便地将标准的HTML网页转换为XML的DOM对象,然后,通过XPath和XSTL将需要的内容抽取出来。

3、下载地址:http://sourceforge.net/projects/jtidy

4、JTidy的代码实现iew plain

package com.qianyan.test;    import java.io.File;  import java.io.FileInputStream;  import java.io.FileOutputStream;  import java.io.InputStreamReader;    import org.w3c.dom.Document;  import org.w3c.tidy.Tidy;    public class TestJTidy {        public static void main(String[] args) throws Exception {          FileInputStream fis = new FileInputStream(new File("E:/baidu.htm"));          InputStreamReader isr = new InputStreamReader(fis, "GBK");                    FileOutputStream fos = new FileOutputStream(new File("E:/baidu.xml"));          Tidy tidy = new Tidy();          tidy.setXmlTags(true);          Document doc = tidy.parseDOM(isr, null);          tidy.pprint(doc, fos);          fos.close();          fis.close();          isr.close();      }  } 



四、使用Nekohtml

1、Nekohtml是一个Java语言的HTML扫描器和标签补全器(tag balancer),使得程序能解析HTML文档并用标准的XML借口来访问其中的信息。这个解析器能够扫描HTML文件并“修正”许多作者(人或机器)在编写HTML文档过程中常犯的错误。

2、Nekohtml能增补缺失的父元素、自动用结束标签关闭相应的元素,以及不匹配的内嵌元素标签。

NekoHTML的开发使用了Xerces Native Interface(XNI),后者是Xerces2的实现基础。

3、下载地址:http://nekohtml.sourceforge.net/index.html

4、代码实现:

package com.qianyan.test;    import java.io.BufferedReader;  import java.io.FileReader;    import org.cyberneko.html.parsers.DOMParser;  import org.w3c.dom.Document;  import org.w3c.dom.Element;  import org.w3c.dom.Node;  import org.w3c.dom.NodeList;  import org.xml.sax.InputSource;    public class TestNekoHTML {            public static String textExtractor(Node root){             //若是文本的话,直接返回             if (root.getNodeType() == Node.TEXT_NODE) {              return root.getNodeValue().trim();             }             if(root.getNodeType() == Node.ELEMENT_NODE) {              Element elmt = (Element) root;              //抛弃脚本              if (elmt.getTagName().equals("STYLE")                || elmt.getTagName().equals("SCRIPT")                ||elmt.getTagName().equals("BR"))               return "";                           NodeList children = elmt.getChildNodes();              StringBuilder text = new StringBuilder();              for (int i = 0; i < children.getLength(); i++) {               text.append(textExtractor(children.item(i)));              }              return text.toString();             }             //对其他类型的节点,返回空值             return "";          }            /**      * @param args      * @throws Exception       */      public static void main(String[] args) throws Exception {          DOMParser parser=new DOMParser();          BufferedReader reader=new BufferedReader(new FileReader("e:/baidu1.htm"));          parser.parse(new InputSource(reader));          Document doc=parser.getDocument();          Node body=doc.getElementsByTagName("body").item(0);          String str=textExtractor(body);          System.out.println(str);                }    }  



五、使用HTMLParser

1、HTML Parser是一个对HTML进行分析的快速实时的解析器。

2、用法:

1)Visitor

2))Filter

3、下载地址:http://htmlparser.sourceforget.net/

4、代码实现:

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  //  @Ignore      public 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      @Ignore      public 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      @Ignore      public 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      @Ignore      public 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      @Ignore      public 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());      }  } 



使用htmlparser 获得页面中的所有超链接

import org.htmlparser.NodeFilter;import org.htmlparser.Parser;import org.htmlparser.filters.TagNameFilter;import org.htmlparser.tags.LinkTag;import org.htmlparser.util.NodeList;import org.htmlparser.util.ParserException;import org.htmlparser.visitors.HtmlPage;public class ParserHtmlPage {    public NodeList parser(String url) throws ParserException{        /**根据url创建parser对象,   || Parser parser = Parser.createParser(url,encoding)**/        Parser parser =  new Parser(url);               /**设置编码,必须与url编码一样,否则挂掉 **/        parser.setEncoding("utf-8");               /** 构建一个html页面对象 **/        HtmlPage htmlPage = new HtmlPage(parser);        parser.visitAllNodesWith(htmlPage);               /** 获取body下面所有的节点 **/        NodeList list = htmlPage.getBody();               /** 建立一个filter,用于过滤节点 **/        NodeFilter filter = new TagNameFilter("A");               /** 得到过滤后的节点 **/        list = list.extractAllNodesThatMatch(filter, true);                      for(int c =0; c < list.size(); c ++){                LinkTag linkTag = (LinkTag) list.elementAt(c);                System.out.println("["+linkTag.getStringText()+"]"+linkTag.getAttribute("href"));//取得href属性的值                //System.out.println(linkTag.getStringText());//取得链接的 文本        }        return list;    }       public static void main(String[] args) throws ParserException {       ParserHtmlPage pp = new ParserHtmlPage();       pp.parser("http://www.baidu.com");    }}