HTML是WEB的核心,網路中你看到的所有頁面都是HTML,不管它們是由JavaScript,JSP,PHP,ASP或是別的什麼WEB技術動態產生的。你的瀏覽器會去解析HTML並替你去渲染它們。不過如果你需要自己在Java程式中解析HTML文件並尋找某些元素,標籤,屬性或檢查某個特定的元素是否存在的話,那又該如何呢?如果你已經使用Java程式設計多年了,我相信你肯定試過解析XML,也使用過類似DOM或SAX這樣的解析器,不過很有可能你從未進行過任何的HTML解析的工作。更諷刺的是,在Java應用程式中,很少會有需要你去解析HTML文件的時候,這裡並不包含Servlet或其它的Java WEB技術。更糟的是,JDK核心裡也沒有包含HTTP或HTML的函式庫,至少我不知道有這個。這就是為什麼一碰上解析HTML檔案時,許多Java程式設計師就得先Google一下,看看如何在Java中取出一個HTML的標籤。當我有這個需要的時候,我相信肯定會有一些開源函式庫能實現這個,不過我沒有想到竟然有JSoup這麼酷的並且功能齊全的函式庫。它不僅能支援讀取並解析HTML文檔,還能讓你從HTML文件抽取任何的元素,以及它們的屬性,它們的CSS屬性,你還能進它們進行修改。有了JSoup你簡直可以對HTML文件做任何事。我們將會看到如何在Java中從google主頁或任何URL下載並解析HTML檔案的範例。
JSoup函式庫是什麼
Jsoup是一個開源的Java函式庫,它可以用來處理實際應用中的HTML。它提供了非常方便的API來進行資料的提取及修改,充分利用了DOM,CSS以及jquery風格方法的長處。 Jsoup實作了WAHTWG HTML5的規範,它從HTML解析出來的DOM和Chrome以及Firefox這樣的現代瀏覽器解析出來的完全一致。以下是Jsoup函式庫的一些有用的特性:
1.Jsoup可以從URL,文件,或字串中取得並解析HTML。
2.Jsoup可以找到並提取數據,可以使用DOM遍歷或CSS選擇器。
3.你可以使用Jsoup來修改HTML元素,屬性以及文字。
4.Jsoup透過一個安全的白名單確保了用戶提交的內容是乾淨的,以防止XSS攻擊。
5.Jsoup還能輸出整潔的HTML。
Jsoup的設計初衷是用來處理現實生活中出現的各種不同的HTML,包括正確有效的HTML以及不完整的無效的標籤集合。 Jsoup的一個核心競爭力就是它的健全性。
在Java中使用Jsoup進行HTML解析
在這篇Java HTML解析的教學中,我們會看到在Java中使用Jsoup解析及遍歷HTML的三個不同的範例。在第一個例子中,我們會解析一個HTML字串,它的內容就是Java中的字串字面量所組成的標籤。在第二個範例中,我們會從WEB下載HTML文檔,而第三個範例中,我們會載入一個HTML範例文件login.html來進行解析。這個檔案是一個HTML文件的範例,它包含title標籤,body裡面有一個div標籤,裡麵包含一個表單。它擁有input標籤來用來取得使用者名稱及密碼,同時也有提交及重設的按鈕用來進行下一步操作。它是一個正確有效的HTML,也就是說,所有的標籤和屬性都是正確地閉合的。下面是我們這個HTML的範例檔:
複製代碼代碼如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Login Page</title>
</head>
<body>
<div id="login" >
<form action="login.do">
Username : <input id="username" type="text" /><br>
Password : <input id="password" type="password" /><br>
<input id="submit" type="submit" />
<input id="reset" type="reset" />
</form>
</div>
</body>
</html>
使用Jsoup來解析HTML非常簡單,你只需呼叫它的靜態方法Jsoup.parse()並傳入你的HTML字串給它就可以了。 Jsoup提供了多個重載的parse()方法,它可以從字串,文件,URI,URL,甚至InputStream中讀取HTML檔案。如果不是UTF-8編碼的話,你也可以指定字元編碼,這樣可以正確地讀取HTML檔。下面是Jsoup函式庫中HTML解析方法的一個完整的清單。 parse(String html)方法將輸入的HTML解析成一個新的Document。在Jsoup裡,Document繼承了Element,它又繼承自Node。同樣的TextNode也繼承自Node。只要你傳入的是一個不為null的字串,你就一定能取得到一個成功的有意義的解析,得到一個包含head和body元素的Document。一旦你拿到這個Document,你就可以呼叫Document以及它的父類別Element和Node上面的適當的方法來取得你想要的資料了。
解析HTML文件的Java程序
下面是一個解析HTML字串,網路上下載的HTML文件,以及本機檔案系統中的HTML文件的完整的Java程式。你可以使用Eclipse IDE或別的IDE甚至命令來執行這個程式。在Eclipse裡面則很簡單,拷貝這份程式碼,新建一個Java工程,在src包上右鍵並貼進去就可以了。 Eclipse會去建立正確的套件及同名的Java原始檔的,因此工作量最小。如果你已經有一個Java範例工程了,那麼只要一步就可以了。下面的這個Java程式展示了解析及遍歷HTML檔案的三個不同範例。在第一個例子中,我們直接解析了一個內容為HTML的字串,第二個例子中我們解析了一個從URL下載的HTML文件,第三個我們從本地文件系統載入了一個HTML文檔並進行解析。第一和第三個範例中都用到了parse方法來取得一個Document對象,你可以查詢它來提取出任何的標籤值或屬性值。在第二個範例中,我們使用了Jsoup.connect方法,它會去建立URL的連接,下載HTML並進行解析。這個方法也會回傳Document,它可以用於後續的查詢及取得標籤或屬性的值。
複製代碼代碼如下:
import java.io.IOException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
/**
[*] Java Program to parse/read HTML documents from File using Jsoup library.
[*] Jsoup is an open source library which allows Java developer to parse HTML
[*] files and extract elements, manipulate data, change style using DOM, CSS and
[*] JQuery like method.
[*]
[*] @author Javin Paul
[*]/
public class HTMLParser{
public static void main(String args[]) {
// Parse HTML String using JSoup library
String HTMLSTring = "<!DOCTYPE html>"
+ "<html>"
+ "<head>"
+ "<title>JSoup Example</title>"
+ "</head>"
+ "<body>"
+ "|[b]HelloWorld[/b]"
+ ""
+ "</body>"
+ "</html>";
Document html = Jsoup.parse(HTMLSTring);
String title = html.title();
String h1 = html.body().getElementsByTag("h1").text();
System.out.println("Input HTML String to JSoup :" + HTMLSTring);
System.out.println("After parsing, Title : " + title);
System.out.println("Afte parsing, Heading : " + h1);
// JSoup Example 2 - Reading HTML page from URL
Document doc;
try {
doc = Jsoup.connect("http://google.com/").get();
title = doc.title();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Jsoup Can read HTML page from URL, title : " + title);
// JSoup Example 3 - Parsing an HTML file in Java
//Document htmlFile = Jsoup.parse("login.html", "ISO-8859-1"); // wrong
Document htmlFile = null;
try {
htmlFile = Jsoup.parse(new File("login.html"), "ISO-8859-1");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // right
title = htmlFile.title();
Element div = htmlFile.getElementById("login");
String cssClass = div.className(); // getting class form HTML element
System.out.println("Jsoup can also parse HTML file directly");
System.out.println("title : " + title);
System.out.println("class of div tag : " + cssClass);
}
}
輸出:
複製代碼代碼如下:
Input HTML String to JSoup :<!DOCTYPE html><html><head><title>JSoup Example</title></head><body><table><tr><td><h1>HelloWorld</h1> </tr></table></body></html>
After parsing, Title : JSoup Example
Afte parsing, Heading : HelloWorld
Jsoup Can read HTML page from URL, title : Google
Jsoup can also parse HTML file directly title : Login Page
class of div tag : simple
Jsoup的好處就是它的健壯性很強。 Jsoup HTML解析器會對你提供的HTML進行盡量乾淨的解析,而不去考慮這個HTML是否是格式良好的。它可以處理以下這些錯誤:未閉合的標籤(例如,Java <p>Scala to <p>JavaScala),隱式標籤(例如,一個裸的|Java is Great被封裝到了|裡面),它總是可以創建出一個文件結構(包含head及body的HTML,並且head裡只會包含正確的元素)。這就是在Java中如何進行HTML的解析。 Jsoup是一個優秀的健壯的開源庫,它使得讀取HTML文檔,body片段,HTML字串,以及直接從WEB中解析HTML內容都變得相當簡單。在這篇文章中,我們學習瞭如何在Java中獲取一個特定的HTML標籤,正如第一個例子中我們將title及H1標籤的值提取成了文本,而第三個例子中我們學習到瞭如何通過提取CSS屬性來從HTML標籤中取得屬性值。除了強大的jQuery風格的html.body().getElementsByTag("h1").text()方法,你還可以提取任意的HTML標籤,它還提供了像Document.title()和Element.className()這樣便捷的方法,你可以快速取得到標題及CSS類別。希望JSoup能讓你玩得愉快,很快我們將會看到更多關於這個API的例子的例子。