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

NekoHTML能增补缺失的父元素、自动用结束标签关闭相应的元素,以及不匹配的内嵌元素标签。NekoHTML的开发使用了 Xerces Native Interface (XNI),后者是Xerces2的实现基础。

 

现在流行的HTML解析工具主要有HTML Parser和nekohtml,我就不细介绍他们了,有兴趣的话可以自己google。个人比较喜欢用nekohtml+xerces,xerces实 际上也是一个XML的解析包,nekohtml建筑在其之上,两者搭配后可将网页解析成一颗DOM树,这样我们对于网页的操作就转化为对这棵树的操作了, 而这正是它和HTML Parser的不同之处,也是我喜欢它的原因。
     我们对网页的操作主要通过org.w3c.dom中提供的接口(nekohtml+xerces提供这些接口的实现),熟悉XML解析的朋友对这个包一定 不会陌生。这个包中用的比较多的接口有:Node、Document、Element、Text等。Node是DOM树中所有节点根接口,它的子接口有 Document、ProcessingInstruction、Element、Comment、Text等,具体的继承层次请参考java doc。正如这些接口的名字说显示的,它们对应于DOM树中相应的元素,这里我就不细说了,下面我们通过一个例子来说明它们的使用方法。
     从网页中抽取文本是一项很平常的工作,HTML Parser中提供了一个TextExtractingVisitor来实现这一点,但nekohtml没有现成这样的类,我们自己写一个也不难:

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 Demo {
 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"))
      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 "";
 }
 public static void main(String[] args) throws Exception{
    //生成html parser
    DOMParser parser = new DOMParser();
    //设置网页的默认编码
    parser.setProperty(
      "http://cyberneko.org/html/properties/default-encoding ",
      "gb18030");
    //input file
    BufferedReader in = new BufferedReader(new FileReader("input.htm"));
    parser.parse(new InputSource(in));
    Document doc = parser.getDocument();
    //获得body节点,以此为根,计算其文本内容
    Node body = doc.getElementsByTagName("BODY").item(0);
    System.out.println(TextExtractor(body));
 }
 }

     除了提供DOM接口外,nekohtml还有一些其他功能,如格式化网页文本、确保网页格式良好(well-formed)等,具体可参见nekohtml的文档