編輯室臺大首頁計中首頁
第0032期 • 2015.03.20發行
ISSN 2077-8813
歷史回顧 訂閱/取消 校務服務 專題報導   技術論壇 推薦刊物
首頁 > 技術論壇
技術論壇

以 jsoup 來解析Yahoo奇摩字典查詢結果

作者:楊德倫 / 臺灣大學計算機及資訊網路中心教學研究組幹事

進行網頁探勘專案開發時,難免有擷取與解析網頁元素的需求,HTML解析器,jsoup正是為您進行這項工作的利器!

前言
jsoup是一個java套件,為需要擷取與操作HTML的程式提供類似於DOM、CSS、jQuery方法的介面。同時,jsoup實作了WHATWG HTML5所定義的規格,解析的方法與目前主流瀏覽器的方法一致。本案例將透過Yahoo奇摩字典查詢的方法網頁,以eclipse開發環境來進行程式撰寫,搭配jsoup功能以取得到我們感興趣的資料,做為未來資料分析之用。

預先裝載相關函式庫
請先至jsoup官方網站下載jsoup-1.8.1.jar,將其掛載至eclipse程式撰寫平台,透過加入外部JARs,來掛載jsoup java library,以供後續使用。


圖一 jsoup java library下載頁面


圖二 透過加入外部JARs,來掛載jsoup java library

範例程式碼分享
以下程式碼可自行複製和使用:

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class ParseDictionary
{
    //seletor 的變數
    public Document doc;
   
    //被 seletor 蒐集到的 html 元素集合
    public Elements results;

   //主要程式執行區域
public static void main(String[] args)
{
    try
    {
       ParseDictionary obj = new ParseDictionary();
       obj.showResult("good");
    }
    catch(Exception e)
    {
       e.printStackTrace();
    }
}

//設定查詢文字
public void setParserConnect(String vocabulary)
{
    try
    {
       doc = Jsoup.connect("http://tw.dictionary.search.yahoo.com/search?p=" + vocabulary + "&fr2=dict").get();
       results = doc.select("ol li[class=result_cluster_first res]");
    }
    catch(Exception e)
    {
       e.printStackTrace();
    }
}

    //顯示測試結果
    public void showResult(String vocabulary)
    {
       try
       {
           //ParseDictionary parse = new ParseDictionary();
           this.setParserConnect( vocabulary );
          
           //抓取單字的詞性、解釋、例句
           Elements main_result = this.results.select("ul[class=explanation_wrapper] > li[class=explanation_pos_wrapper]");
           for(Element result : main_result )
           {
              System.out.println("詞性(英文): " + result.select("h5[class=explanation_group_hd] > span[class=pos_abbr]").text() );
              System.out.println( "詞性(中文)" + result.select("h5[class=explanation_group_hd] > span[class=pos_desc]").text() );
             
              for(Element r : result.select("ol[class=explanation_ol] > li") )
              {
                  System.out.println( "解釋: " + r.select("p[class=explanation]").text() );
                  System.out.println( "例句: " + r.select("p[class=sample]").text() );
              }
             
              System.out.println();
              System.out.println();
           }
          
           //單字形態變化
           Elements diversity_result = this.results.select("ul[class=extra_wrapper] li").eq(0);
           System.out.println("動詞變化: " + diversity_result.select("div[class=extra_wordlist] > p:nth-child(1) span").eq(1).text() );
           System.out.println("複詞: " + diversity_result.select("div[class=extra_wordlist] > p:nth-child(2) span").eq(1).text() );
           System.out.println();
           System.out.println();
          
           //同義字
           System.out.println("同義字:";);
           Elements synonym_result = this.results.select("ul[class=extra_wrapper] li";).eq(1);
           for(Element synonym_r : synonym_result.select("div[class=extra_wordlist]") )
           {
               System.out.println( synonym_r.select("p").text() );
              for(Element synonym_rr : synonym_r.select("samp a") )
              {
                  System.out.println( synonym_rr.text() );
              }
           }
           System.out.println();
           System.out.println();
          
           //反義字
           System.out.println("反義字:");
           Elements antonym_result = this.results.select("ul[class=extra_wrapper] li").eq(2);
           for(Element antonym_r : antonym_result.select("div[class=extra_wordlist]") )
           {
               System.out.println( antonym_r.select("p").text() );
              for(Element antonym_rr : antonym_r.select("samp a") )
              {
                  System.out.println( antonym_rr.text() );
              }
           }
           System.out.println();
           System.out.println();      
       }
       catch(Exception e)
       {
           e.printStackTrace();
       }
    }
}

執行結果
若例句或結果有空白未顯示部分,代表該詞彙或例句在網頁結果中並無資料;我們以單字「good」為例,透過上列程式碼執行,呈現結果如下:


圖三 形容詞部分


圖四 名詞部分


圖五 動詞變化及複詞


圖六 同義字


圖七 反義字

原始網頁呈現結果


圖八 原始網頁呈現結果

後記
jsoup擁有良好的且可擴充的API,我們可以透過selector的設定來開發出非常強大的HTML解析功能,本身的相關資訊也有許多人進行討論。倘若您對jQuery、CSS selector有一些了解,不妨一試!

參考資料
[1] eclipse download
https://eclipse.org/downloads/
[2] jsoup: Java HTML Parser
http://jsoup.org/
[3] 使用JSOUP讓JAVA取得網頁上的文字
http://a6350202.pixnet.net/blog/post/148400470
[4] Yahoo奇摩字典搜尋
http://tw.dictionary.search.yahoo.com/?fr
[5] 維基百科:網頁超文字技術工作小組(WHATWG)
http://zh.wikipedia.org/wiki/網頁超文本技術工作小組

版權所有 © 國立台灣大學計算機及資訊網路中心 AllRights Reserved.
電話:02-33665022 或 3366-5023 傳真: 02-23637204
讀者意見信箱:ntuccepaper@ntu.edu.tw
地址:10617 臺北市羅斯福路四段一號
建議最佳螢幕解析度 1024*768