关于这个工具的简介就不说了,这里只介绍其用法。
(一),来看它的API:
Packages
org.htmlparser
org.htmlparser.beans
org.htmlparser.filters
org.htmlparser.http
org.htmlparser.lexer
org.htmlparser.lexerapplications.thumbelina
org.htmlparser.nodes
org.htmlparser.parserapplications
org.htmlparser.parserapplications.filterbuilder
org.htmlparser.parserapplications.filterbuilder.layouts
org.htmlparser.parserapplications.filterbuilder.wrappers
org.htmlparser.sax
org.htmlparser.scanners
org.htmlparser.tags
org.htmlparser.util
org.htmlparser.util.sort
org.htmlparser.visitors
点击上面的链接,每一个类都有详细的方法和字段释义。在此,我们常用到的几个类是:Parser; Filter; Util; Node; Tags;
(二),使用htmlparser的最一般方法,可以分为下面几个步骤:
1)
和目标网页(目标网页可以是网络上的一个URL,也可以是一个本地的网页文件)建立连接;
2)
定义解析器(Parser),解析器可以设定要解析的目标页,可以设定解析页面时的编码;
3)
构造过滤器,htmlParser给我们提供的过滤器类型有很多,大致分为简单过滤器(TagNameFilter)和复合型过滤器(AndFilter),简单过滤器即过滤某个标签的名称或属性,复合过滤器可以包含多个简单过滤器,并对它进行逻辑运算;
4)
使用定义好的解析器和过滤器解析页面,此时返回给我们的是一个包含所有符合条件的Node数组;
5)
循环该数组,并对数组中的每一个节点进行解析(一般都是将这些节点转化为某一个具体的html标签),取得需要的节点属性。
(三),按照上面的步骤,可以做一个最简单的htmlParser解析的实例(假设我们解析百度首页中的超链接信息):
例程1 写道
package com.crawler;
import java.net.URL;
import java.net.URLConnection;
import org.htmlparser.Node;
import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.filters.AndFilter;
import org.htmlparser.filters.HasAttributeFilter;
import org.htmlparser.filters.TagNameFilter;
import org.htmlparser.tags.LinkTag;
import org.htmlparser.util.NodeIterator;
import org.htmlparser.util.NodeList;
public class HtmlParserTest1 {
public static void main(String[] args) throws Exception {
URL url = new URL("http://www.baidu.com");
URLConnection urlConn = url.openConnection();
Parser parser = new Parser(urlConn);
NodeFilter nodeFilter = new AndFilter(new TagNameFilter("a"),
new HasAttributeFilter("href"));
NodeList nodeList = parser.parse(nodeFilter);
NodeIterator it = nodeList.elements();
while (it.hasMoreNodes()) {
Node node = it.nextNode();
System.out.println(((LinkTag) node).getAttribute("href"));
}
}
}
(四)如果只是实现常见的功能,了解了上面方法和步骤,然后查看其API,自然都可以做到了,但如果我们要做一些更高级的功能,就必须对这个工具进行扩展,由于htmlParser定义良好的接口,我们可以方便的写出自己想要的网页解析工具,在这里我举一个例子,假如我们要对WML(无线标记语言,常用于移动设备的web开发)进行解析,这里就涉及到一些新的标签,比如go,anchor,postfield等,同样,我给出一个简单的示例:
首先,这是我们的wml网页内容:test.wml 写道
<a href="http://www.iteye.com?cat_id=1">Javaeye</a>
或者:
<anchor>
Java自由人
<go href="http://www.iteye.com" method="get">
<postfield name="cat_id" value="1"/>
</go>
</anchor>
具体的解析代码,HyperLinkTrace.java 写道
package com.htmlParser;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import org.htmlparser.Node;
import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.PrototypicalNodeFactory;
import org.htmlparser.tags.CompositeTag;
import org.htmlparser.tags.LinkTag;
import org.htmlparser.util.NodeList;
public class HyperLinkTrace {
public static void main(String[] args) throws Exception {
// 初始化HTMLParser
Parser parser = new Parser();
parser.setEncoding("8859_1");
parser.setInputHTML(getWmlContent());
// 注册新的结点解析器
PrototypicalNodeFactory factory = new PrototypicalNodeFactory();
factory.registerTag(new WmlGoTag());
parser.setNodeFactory(factory);
// 遍历符合条件的所有节点
NodeList nlist = parser.extractAllNodesThatMatch(lnkFilter);
for (int i = 0; i < nlist.size(); i++) {
CompositeTag node = (CompositeTag) nlist.elementAt(i);
if (node instanceof LinkTag) {
LinkTag link = (LinkTag) node;
System.out.println("LINK: \t" + link.getLink());
} else if (node instanceof WmlGoTag) {
WmlGoTag go = (WmlGoTag) node;
System.out.println("GO: \t" + go.getLink());
}
}
}
/**
* 获取测试的WML脚本内容
*
* @return
* @throws Exception
*/
static String getWmlContent() throws Exception {
File f = new File("test.wml");
BufferedReader in = new BufferedReader(new FileReader(f));
StringBuffer wml = new StringBuffer();
do {
String line = in.readLine();
if (line == null)
break;
if (wml.length() > 0)
wml.append("\r\n");
wml.append(line);
} while (true);
return wml.toString();
}
/**
* 解析出所有的链接,包括行为<a>与<go>
*/
static NodeFilter lnkFilter = new NodeFilter() {
public boolean accept(Node node) {
if (node instanceof WmlGoTag)
return true;
if (node instanceof LinkTag)
return true;
return false;
}
};
/**
* WML文档的GO标签解析器
*
* @author Winter Lau
*/
static class WmlGoTag extends CompositeTag {
private static final String[] mIds = new String[] { "GO" };
private static final String[] mEndTagEnders = new String[] { "ANCHOR" };
public String[] getIds() {
return (mIds);
}
public String[] getEnders() {
return (mIds);
}
public String[] getEndTagEnders() {
return (mEndTagEnders);
}
public String getLink() {
return super.getAttribute("href");
}
public String getMethod() {
return super.getAttribute("method");
}
}
}
以上这个示例的来源是:http://www.ibm.com/developerworks/cn/opensource/os-htmlparser/
读完上面的文章应该对此用法有更深入的认识。
接下来,我还会写几篇文章对htmlParser的一些用法上细节做一介绍。