需要做一個垂直搜尋引擎,比較了nekohtml和htmlparser 的功能,儘管nekohtml在容錯性、效能等方面的口碑好像比htmlparser好(htmlunit也用的是nekohtml),但感覺nekohtml的測試案例和文檔都比htmlparser都少,而且htmlparser基本上能夠滿足垂直搜尋引擎頁面處理分析的需求,因此先研究一下htmlparser的使用,有空再研究nekohtml和mozilla html parser的使用。
html的功能還是官方說得最為清楚,
HTML Parser is a Java library used to parse HTML in either a linear or nested fashion. Primarily used for transformation or extraction, it features filters, visitors, custom tags and easy to use JavaBeans. It is a fast, robust and well tested package.
The two fundamental use-cases that are handled by the parser are extraction and transformation (the syntheses use-case, where HTML pages are created from scratch, is better handled by other tools closer to the source of data). While prior versions concentrated on data extraction from web pages, Version 1.4 of the HTMLParser has substantial improvements in the area of transforming web pages, with simplified tag creation and editing, and verbatim toHtml() method output.
研究的重點還是extraction的使用,有空再研究transformation的使用。
1、htmlparser對html頁面處理的資料結構
,HtmlParser採用了經典的Composite模式,通過RemarkNode、TextNode、TagNode、AbstractNode和Tag來描述HTML頁面各元素。
org.htmlparser.Node:
Node介面定義了進行樹形結構節點操作的各種典型操作方法,包括:
節點到html文本、text文本的方法:toPlainTextString、toHtml
典型樹形結構遍曆的方法:getParent、getChildren、getFirstChild、getLastChild、getPreviousSibling、getNextSibling、getText
擷取節點對應的樹形結構結構的頂級節點Page對象方法:getPage
擷取節點起始位置的方法:getStartPosition、getEndPosition
Visitor方法遍曆節點時候方法:accept (NodeVisitor visitor)
Filter方法:collectInto (NodeList list, NodeFilter filter)
Object方法:toString、clone
org.htmlparser.nodes.AbstractNode:
AbstractNode是形成HTML樹形結構抽象基類,實現了Node介面。
在htmlparser中,Node分成三類:
RemarkNode:代表Html中的注釋
TagNode:標籤節點。
TextNode:文本節點
這三類節點都繼承AbstractNode。
org.htmlparser.nodes.TagNode:
TagNode包含了對HTML處理的核心的各個類,是所有TAG的基類,其中有分為包含其他TAG的複合節點ComositeTag和不包含其他TAG的葉子節點Tag。
複合節點CompositeTag:
AppletTag,BodyTag,Bullet,BulletList,DefinitionList,DefinitionListBullet,Div,FormTag,FrameSetTag,HeadingTag,
HeadTag,Html,LabelTag,LinkTag,ObjectTag,ParagraphTag,ScriptTag,SelectTag,Span,StyleTag,TableColumn,
TableHeader,TableRow,TableTag,TextareaTag,TitleTag
葉子節點TAG:
BaseHrefTag,DoctypeTag,FrameTag,ImageTag,InputTag,JspTag,MetaTag,ProcessingInstructionTag,
2、htmlparser對html頁面處理的演算法
主要是如下幾種方式
採用Visitor方式訪問Html
try {
Parser parser = new Parser();
parser.setURL(”http://www.google.com/”);
parser.setEncoding(parser.getEncoding());
NodeVisitor visitor = new NodeVisitor() {
public void visitTag(Tag tag) {
logger.fatal(”testVisitorAll() Tag name is :”
+ tag.getTagName() + ” \n Class is :”
+ tag.getClass());
}
};
parser.visitAllNodesWith(visitor);
} catch (ParserException e) {
e.printStackTrace();
}
採用Filter方式訪問html
try {
NodeFilter filter = new NodeClassFilter(LinkTag.class);
Parser parser = new Parser();
parser.setURL(”http://www.google.com/”);
parser.setEncoding(parser.getEncoding());
NodeList list = parser.extractAllNodesThatMatch(filter);
for (int i = 0; i < list.size(); i++) {
LinkTag node = (LinkTag) list.elementAt(i);
logger.fatal(”testLinkTag() Link is :” + node.extractLink());
}
} catch (Exception e) {
e.printStackTrace();
}
採用org.htmlparser.beans方式
另外htmlparser 還在org.htmlparser.beans中對一些常用的方法進行了封裝,以簡化操作,例如:
Parser parser = new Parser();
LinkBean linkBean = new LinkBean();
linkBean.setURL(”http://www.google.com/”);
URL[] urls = linkBean.getLinks();
for (int i = 0; i < urls.length; i++) {
URL url = urls;
logger.fatal(”testLinkBean() -url is :” + url);
}
3、htmlparser關鍵包結構說明
htmlparser其實核心代碼並不多,好好研究一下其代碼,彌補文檔不足的問題。同時htmlparser的代碼注釋和單元測試用例還是很齊全的,也有助於瞭解htmlparser的用法。
3.1、org.htmlparser
定義了htmlparser的一些基礎類。其中最為重要的是Parser類。
Parser是htmlparser的最核心的類,其建構函式提供了如下:Parser.createParser (String html, String charset)、 Parser ()、Parser (Lexer lexer, ParserFeedback fb)、Parser (URLConnection connection, ParserFeedback fb)、Parser (String resource, ParserFeedback feedback)、 Parser (String resource)
各建構函式的具體用法及含義可以查看其代碼,很容易理解。
Parser常用的幾個方法:
elements擷取元素
Parser parser = new Parser (”http://www.google.com/”);
for (NodeIterator i = parser.elements (); i.hasMoreElements (); )
processMyNodes (i.nextNode ());
parse (NodeFilter filter):通過NodeFilter方式擷取
visitAllNodesWith (NodeVisitor visitor):通過Nodevisitor方式
extractAllNodesThatMatch (NodeFilter filter):通過NodeFilter方式
3.2、org.htmlparser.beans
對Visitor和Filter的方法進行了封裝,定義了針對一些常用html元素操作的bean,簡化對常用元素的提取操作。
包括:FilterBean、HTMLLinkBean、HTMLTextBean、LinkBean、StringBean、BeanyBaby等。
3.3、org.htmlparser.nodes
定義了基礎的node,包括:AbstractNode、RemarkNode、TagNode、TextNode等。
3.4、org.htmlparser.tags
定義了htmlparser的各種tag。
3.5、org.htmlparser.filters
定義了htmlparser所提供的各種filter,主要通過extractAllNodesThatMatch (NodeFilter filter)來對html頁面指定類型的元素進行過濾,包括:AndFilter、CssSelectorNodeFilter、HasAttributeFilter、HasChildFilter、HasParentFilter、HasSiblingFilter、IsEqualFilter、LinkRegexFilter、LinkStringFilter、NodeClassFilter、NotFilter、OrFilter、RegexFilter、StringFilter、TagNameFilter、XorFilter
3.6、org.htmlparser.visitors
定義了htmlparser所提供的各種visitor,主要通過visitAllNodesWith (NodeVisitor visitor)來對html頁面元素進行遍曆,包括:HtmlPage、LinkFindingVisitor、NodeVisitor、ObjectFindingVisitor、StringFindingVisitor、TagFindingVisitor、TextExtractingVisitor、UrlModifyingVisitor
3.7、org.htmlparser.parserapplications
定義了一些實用的工具,包括LinkExtractor、SiteCapturer、StringExtractor、WikiCapturer,這幾個類也可以作為htmlparser使用範例。
3.8、org.htmlparser.tests
對各種功能的單元測試用例,也可以作為htmlparser使用的範例。