Jsoup代碼解讀之一-概述

LonGillilan 8年前發布 | 12K 次閱讀 HTML Java開發

來自: http://www.importnew.com/17746.html

今天看到一個用python寫的抽取正文的東東,美滋滋的用Java實現了一番,放到了webmagic里,然后發現Jsoup里已經有了…覺得自己各種不靠譜啊!算了,靜下心來學學好東西吧!

Jsoup是Java世界用作html解析和過濾的不二之選。支持將html解析為DOM樹、支持CSS Selector形式選擇、支持html過濾,本身還附帶了一個Http下載器。從今天開始會寫一個Jsoup源碼解讀系列,比起之前的博客,盡量會寫的詳盡一些。

概述

Jsoup的代碼相當簡潔,Jsoup總共53個類,且沒有任何第三方包的依賴,對比最終發行包9.8M的SAXON,實在算得上是短小精悍了。

jsoup

├── examples #樣例,包括一個將html轉為純文本和一個抽取所有鏈接地址的例子。

├── helper #一些工具類,包括讀取數據、處理連接以及字符串轉換的工具

├── nodes #DOM節點定義

├── parser #解析html并轉換為DOM樹

├── safety #安全相關,包括白名單及html過濾

└── select #選擇器,支持CSS Selector以及NodeVisitor格式的遍歷

使用

Jsoup的入口是Jsoup類。examples包里提供了兩個例子,解析html后,分別用CSS Selector以及NodeVisitor來操作Dom元素。

這里用ListLinks里的例子來說明如何調用Jsoup:

public static void main(String[] args) throws IOException {
 Validate.isTrue(args.length == 1, "usage: supply url to fetch");
 String url = args[0];
 print("Fetching %s...", url);
// 下載url并解析成html DOM結構
 Document doc = Jsoup.connect(url).get();
 // 使用select方法選擇元素,參數是CSS Selector表達式
 Elements links = doc.select("a[href]");
print("\nLinks: (%d)", links.size());
 for (Element link : links) {
 //使用abs:前綴取絕對url地址
 print(" * a: <%s> (%s)", link.attr("abs:href"), trim(link.text(), 35));
 }
}

Jsoup使用了自己的一套DOM代碼體系,這里的Elements、Element等雖然名字和概念都與Java XML APIorg.w3c.dom類似,但并沒有代碼層面的關系。就是說你想用XML的一套API來操作Jsoup的結果是辦不到的,但是正因為如此,才使得Jsoup可以拋棄xml里一些繁瑣的API,使得代碼更加簡單。

還有一種方式是通過NodeVisitor來遍歷DOM樹,這個在對整個html做分析和替換時比較有用:

public interface NodeVisitor {
//遍歷到節點開始時,調用此方法
 public void head(Node node, int depth);
//遍歷到節點結束時(所有子節點都已遍歷完),調用此方法
 public void tail(Node node, int depth);
}
HtmlToPlainText的例子說明了如何使用NodeVisitor來遍歷DOM樹,將html轉化為純文本,并將需要換行的標簽替換為換行\n:

public static void main(String... args) throws IOException { Validate.isTrue(args.length == 1, "usage: supply url to fetch"); String url = args[0]; // fetch the specified URL and parse to a HTML DOM Document doc = Jsoup.connect(url).get(); HtmlToPlainText formatter = new HtmlToPlainText(); String plainText = formatter.getPlainText(doc); System.out.println(plainText); } public String getPlainText(Element element) { //自定義一個NodeVisitor - FormattingVisitor FormattingVisitor formatter = new FormattingVisitor(); //使用NodeTraversor來裝載FormattingVisitor NodeTraversor traversor = new NodeTraversor(formatter); //進行遍歷 traversor.traverse(element); return formatter.toString(); }</pre>

下一節將從DOM結構開始對Jsoup代碼進行分析。

</div>

 本文由用戶 LonGillilan 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!