HTMLParser使用詳解(3)

黄舟
發布: 2016-12-29 15:57:20
原創
1183 人瀏覽過

HTMLParser遍歷了網頁的內容以後,以樹(森林)結構保存了結果。 HTMLParser存取結果內容的方法有兩種。使用Filter和使用Visitor。

(一)Filter類
顧名思義,Filter就是對於結果進行過濾,取得所需的內容。 HTMLParser在org.htmlparser.filters包之內一共定義了16個不同的Filter,也可以分成幾類。
判斷類別Filter:

TagNameFilter
HasAttributeFilter
HasChildFilter
HasParentFilter
HasSiblingFilter
IsEqualFilter
登入後複製

邏輯運算Filter:

AndFilter
NotFilter
OrFilter
XorFilter
其他Filter:
NodeClassFilter
StringFilter
LinkStringFilter
LinkRegexFilter
RegexFilter
CssSelectorNodeFilter
登入後複製

所有的Filter類別都實作了org.htmlparser.NodeFilter介面。這個介面只有一個主要函數:

boolean accept (Node node);
登入後複製

(二)判斷類別FilterHTMLParser使用入門(2)- Node內容,自己加入import部分)

public static void main(String[] args) {
try{
Parser parser = new Parser( (HttpURLConnection) (new URL("http://127.0.0.1:8080/HTMLParserTester.html")).openConnection() );
// 这里是控制测试的部分,后面的例子修改的就是这个地方。
NodeFilter filter = new TagNameFilter ("DIV");
NodeList nodes = parser.extractAllNodesThatMatch(filter); 
if(nodes!=null) {
for (int i = 0; i < nodes.size(); i++) {
Node textnode = (Node) nodes.elementAt(i);
message("getText:"+textnode.getText());
message("=================================================");
}
} 
}
catch( Exception e ) { 
e.printStackTrace();
}
}
登入後複製

輸出結果:

getText:div id="top_main"
=================================================
getText:div id="logoindex"
=================================================
登入後複製
登入後複製

NodeFilter filter = new HasChildFilter();
登入後複製

輸出結果:

NodeFilter innerFilter = new TagNameFilter ("DIV");
NodeFilter filter = new HasChildFilter(innerFilter);
NodeList nodes = parser.extractAllNodesThatMatch(filter);
登入後複製

節點都被取出了。下面可以針對這兩個DIV節點進行操作

2.2 HasChildFilter
下面讓我們來看看HasChildFilter。剛剛看到這個Filter的時候,我想當然地認為這個Filter回傳的是有Child的Tag。直接初始化了一個

getText:body 
=================================================
getText:div id="top_main"
=================================================
登入後複製

修改程式碼:

public HasChildFilter (NodeFilter filter, boolean recursive)
登入後複製

輸出結果:

NodeFilter filter = new HasChildFilter( innerFilter, true );
登入後複製

可以看到,輸出的是兩個有DIV子Tag的Tag節點。 (body有子節點DIV "top_main","top_main"有子節點"logoindex"。


注意HasChildFilter還有一個建構子:

getText:html xmlns="http://www.w3.org/1999/xhtml"
=================================================
getText:body 
=================================================
getText:div id="top_main"
=================================================
登入後複製


如果recursive是false,則只對第一級子節點進行過濾只對第一級子節點進行過濾。看到輸出結果多了一個html xmlns="http://www.w3.org/1999/xhtml",這個是整個HTML頁面的節點(根節點),雖然這個節點下方直接沒有DIV節點,但它的子節點body下面有DIV節點,所以它也被匹配上了。的節點。

public HasAttributeFilter ();
public HasAttributeFilter (String attribute);
public HasAttributeFilter (String attribute, String value);
登入後複製

輸出結果:


NodeFilter filter = new HasAttributeFilter();
NodeList nodes = parser.extractAllNodesThatMatch(filter);
登入後複製

很簡單吧。 Node:

什么也没有输出。
登入後複製

不需要太多說明了。針對類型進行過濾。字串中的內容(例如註釋,連結等等)不會被顯示。字串和連結的文字字串的Tag都被輸出了,但是註解和連結Tag本身沒有輸出。指向某個特定網站的連結。

測試程式碼:

NodeFilter filter = new HasAttributeFilter( "id" );
NodeList nodes = parser.extractAllNodesThatMatch(filter);
登入後複製

輸出結果:

getText:div id="top_main"
=================================================
getText:div id="logoindex"
=================================================
登入後複製
登入後複製

4.4 其他幾個Filter
其他幾個Filter也是根據字串對不同的域進行判斷,與前面這些的區別主要就是支持正則表達式。這個不在本文的討論範圍內,大家可以自己實驗一下。

前面介紹的都是簡單的Filter,只能針對某種單一類型的條件進行過濾。 HTMLParser支援對於簡單類型的Filter進行組合,從而實現複雜的條件。原理和一般程式語言的邏輯運算是一樣的。
3.1 AndFilter
AndFilter可以把兩種Filter進行組合,只有同時滿足條件的Node才會被過濾。
測試程式碼:

NodeFilter filter = new HasAttributeFilter( "id", "logoindex" );
NodeList nodes = parser.extractAllNodesThatMatch(filter);
登入後複製

輸出結果:

getText:div id="logoindex"
=================================================
登入後複製

3.2 OrFilter

把前面的AndFilter換成OrFilter

測試程式碼:

reeeNot

reeeNot
3的輸出結果: ter
測試程式碼:

public IsEqualFilter (Node node) {
mNode = node;
}
accept函数也很简单:
public boolean accept (Node node) {
return (mNode == node);
}
登入後複製

輸出結果:

NodeFilter filter = new NodeClassFilter(RemarkNode.class);
NodeList nodes = parser.extractAllNodesThatMatch(filter);
登入後複製

除了前面3.2中輸出的幾個Tag,其餘的Tag都在這裡了。

3.4 XorFilter
把前面的AndFilter換成NotFilter
測試程式碼:

getText:这是注释
=================================================
可以看到只有RemarkNode(注释)被输出了。
登入後複製

輸出結果:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><title>白泽居-title-www.baizeju.com</title></head>
<html xmlns="http://www.w3.org/1999/xhtml">
<body >
<div id="top_main">
<div id="logoindex">
<!--这是注释 白泽居-www.baizeju.com -->
白泽居-字符串1-www.baizeju.com
<a href="http://www.baizeju.com">白泽居-链接文本-www.baizeju.com</a>
</div>
白泽居-字符串2-www.baizeju.com
</div>
</body>
</html>
登入後複製

4.1 NodeClassFilter
Filter
這個2Node字類型是否是某個特定的節點類型。在

2.1 TagNameFilter

TabNameFilter是最容易理解的一個Filter,根據Tag的名字進行過濾。

下面是用來測試的HTML檔:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><title>白泽居-www.baizeju.com</title>< /head>
<html xmlns="http://www.w3.org/1999/xhtml">
<body >
<div id="top_main">
<div id="logoindex">
<!--这是注释-->
白泽居-www.baizeju.com
<a href="http://www.baizeju.com">白泽居-www.baizeju.com</a>
</div>
白泽居-www.baizeju.com
</div>
</body>
</html>
登入後複製

 以上就是HTMLParser使用详解(3)的内容,更多相关内容请关注PHP中文网(www.php.cn)!


相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板