1. 程式人生 > >利用jsoup解析html

利用jsoup解析html

1、jsoup簡介
jsoup 是一款 Java的HTML解析器,可直接解析某個URL地址、HTML文字內容。它提供了一套非常省力的API,可通過DOM,CSS以及類似於jQuery的操作方法來取出和操作資料。jsoup 的主要功能如下:
(1)從一個 URL,檔案或字串中解析HTML;
(2)使用DOM或CSS選擇器來查詢、取出資料;
(3)可操作HTML元素、屬性、文字;

2、maven配置

<!-- jsoup -->
<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId
>
jsoup</artifactId> <version>1.7.3</version> </dependency>

3、解析一個HTML文件
3.1 從字串解析

String html = "<html><head><title>First parse</title></head>" + "<body><p>Parsed HTML into a doc.</p></body></html>";
<!-- 解析之後可以用Document的方法,拿出html中需要的資料 -->
Document doc = Jsoup.parse(html);

3.2 從URL獲取解析

Document doc = Jsoup.connect("http://example.com/").get();
String title = doc.title();

(1)說明
connect(String url)方法建立一個新的 Connection, 和get()取得和解析一個HTML檔案。如果從該URL獲取HTML時發生錯誤,便會丟擲 IOException,應適當處理。Connection 介面還提供一個方法鏈來解決特殊請求,具體如下:

Document doc = Jsoup.connect("http://www.oschina.net/"
) .data("query", "Java") // 請求引數 .userAgent("I ’ m jsoup") // 設定 User-Agent .cookie("auth", "token") // 設定 cookie .timeout(3000) // 設定連線超時時間 .post(); // 使用 POST 方法訪問 URL

這個方法只支援Web URLs (http和https 協議); 假如你需要從一個檔案載入,可以使用parse(File in, String charsetName) 代替。

3.3 從檔案解析

File input = new File("/tmp/input.html");
Document doc = Jsoup.parse(input, "UTF-8", "http://www.oschina.net/");

(1)說明
parse的第三個引數,需要在這裡指定一個網址(雖然可以不指定),因為HTML文件中會有很多例如連結、圖片以及所引用的外部指令碼、css 檔案等,而第三個名為 baseURL 的引數的意思就是當 HTML 文件使用相對路徑方式引用外部檔案時,jsoup 會自動為這些 URL 加上一個字首,也就是這個 baseURL。
例如 :<a href=/project> 開源軟體 </a> 會被轉換成 <a href=http://www.oschina.net/project> 開源軟體 </a>

4、遍歷一個HTML文件
4.1 Document方式遍歷元素
4.1.1 搜尋元素方法

getElementById(String id)
getElementByTag(String tag)
getElementByClass(String className)
getElementByAttribute(String key)
siblingElements(), firstElementSibling(), lastElementSibling(), nextElementSibling(), previousElementSibling()
parent(), children(), child(int index)

4.1.2 獲取元素資料

attr(String key) – 獲取key屬性
attributes() – 獲取屬性
id(), className(), classNames()
text() – 獲取文字內容
html() – 獲取元素內部HTML內容
outerHtml() – 獲取包括此元素的HTML內容
data() – 獲取<srcipt>或<style>標籤中的內容
tag(), tagName()

4.2 選擇器語法遍歷元素(jsoup與其他解析器的區別就是可以使用類似jquery的選擇器語法來搜尋及過濾出所需的元素)
4.2.1 基本選擇器

tagname: 搜尋tag標籤的元素
ns|tag: 搜尋名稱空間內tag標籤的元素,如fb|name:<fb:name>
id: 搜尋有指定id的元素
.class: 搜尋有指定class的元素
[attribute]: 搜尋有attrribute屬性的元素
[^attri]: 搜尋有以attri開頭的屬性的元素
[attr=value]: 搜尋有指定屬性及其屬性值的元素
[attr^=value], [attr$=value], [attr*=value]: 搜尋有指定attr屬性,且其屬性值是以value開頭、結尾或包括value的元素,如[href*=/path/]
[attr~=regex]: 搜尋有指定attr屬性,且其屬性值符合regex正則表示式的元素
*: 搜尋所有元素

4.2.2 選擇器組合

el#id: 同時指定標籤名稱和id
el.class: 同時指定標籤名稱和class
el[attr]: 同時指定標籤名稱和及其中所含屬性的名稱
上述3項的任意組合,如a[href].highlight
ancestor child: 包含,如div.content p,即搜尋<div class=”content”>下含有<p>標籤的元素
ancestor > child: 直接包含,如div.content > p,即搜尋直屬<div class="content">節點下的<p>標籤元素;div.content > *,即搜尋<div class="content">下的所有元素
siblingA + siblingB: 直接遍歷,如div.head + div,即搜尋<div class="head"><div>的元素,其中不再包含子元素
siblingA ~ siblingX: 遍歷,如h1 ~ p,即<h1>下直接或間接有<p>的元素
el, el, el: 組合多個選擇器,搜尋滿足其中一個選擇器的元素

5、使用範例

/*
  previousSibling()獲取某標籤前面的程式碼
  nextSibling()獲取某標籤後的程式碼
  如:
  <form id=form1>
  第一名:Lily  <br/>
  第二名:Tom   <br/>
  第三名:Peter <br/>
  </form>
*/
Elements items = doc.select("form[id=form1]");
Elements prevs = items.select("br");
for(Element p : prevs){
   String prevStr = p.previousSibling().toString().trim());
}

/*
 最常用的連結抓取
*/
String itemTag = "div[class=mydiv]";
String linkTag = "a"
Elements items = doc.select(itemTag);
Elements links = items.select(linkTag);
for(Element l : links){ 
  String href = l.attr("abs:href");//完整Href
  String absHref = l.attr("href");//相對路徑
  String text = l.text();
  String title = l.attr("title");
}