[Windows Phone] 使用 Html Agility Pack 取得統一發票資訊

  • 4244
  • 0
  • 2013-12-06

在先前的文章 Windows Phone 開發 - 讀取【微軟最有價值專家 Microsoft MVP 台灣粉絲團】RSS,我們透過 WebClient 的方式,下載 RSS 資料,解析後呈現在畫面上。然而,不是每個想要擷取資料的網頁,都有固定的格式讓您抓取資料,例如說想要抓取統一發票的資料,我們可以到以下網址抓取,但無法直接取得統一發票資料。在此,我們可以透過 Html Agility Pack 做網頁分析與擷取資料,透過 xpath 的方式,擷取出想要的資料。

 

說明

在先前的文章 Windows Phone 開發 - 讀取【微軟最有價值專家 Microsoft MVP 台灣粉絲團】RSS,我們透過 WebClient 的方式,下載 RSS 資料,解析後呈現在畫面上。

然而,不是每個想要擷取資料的網頁,都有固定的格式讓您抓取資料,例如說想要抓取統一發票的資料,我們可以到以下網址抓取,但無法直接取得統一發票資料。

http://invoice.etax.nat.gov.tw/

在此,我們可以透過 Html Agility Pack 做網頁分析與擷取資料,透過 xpath 的方式,擷取出想要的資料,關於 Html Agility Pack,可以參考此文章 HTML Agility Pack:簡單好用的快速 HTML Parser ,有詳細介紹。

 

練習

1. 新增專案,在此我新增 Windows Phone 資料繫節應用程式,名稱為 UniformInvoiceApp。

SNAGHTMLbb1271

 

將 Html Agility Pack  加入專案,在專案上按滑鼠右鍵,選擇 [管理 NuGet 套件]。

image

 

搜尋關鍵字 Html Agility Pack,找出 Html Agility Pack 後進行 [安裝]。

SNAGHTMLbcbbac

 

安裝後,還需要額外加入參考 System.Xml.Xpath.dll,請參考下圖說明,加入參考,我是新增 Window Phone 7.1 專案,因此加入的路徑是

C:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Libraries\Client\System.Xml.XPath.dll

image

 

透過瀏覽,加入參考 System.Xml.Xpath.dll

SNAGHTMLbe86b8

 

如果出現警告訊息,請按 [是]。

SNAGHTMLbec0c3

 

確認參考都有加入。

image

 

首先,針對 ItemViewModel.cs 進行變更,預設會有 LineOne、LineTwo、LineThree 三個屬性,我們變更為 Prize 和 Number,儲存獎項與統一發票號碼。

 


using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace UniformInvoiceApp
{
    public class ItemViewModel : INotifyPropertyChanged
    {
        private string _Prize;
        /// <summary>
        /// 範例 ViewModel 屬性; 這個屬性是用在檢視中,以使用繫結來顯示其值。
        /// </summary>
        /// <returns></returns>
        public string Prize
        {
            get
            {
                return _Prize;
            }
            set
            {
                if (value != _Prize)
                {
                    _Prize = value;
                    NotifyPropertyChanged("Prize");
                }
            }
        }

        private string _Number;
        /// <summary>
        /// 範例 ViewModel 屬性; 這個屬性是用在檢視中,以使用繫結來顯示其值。
        /// </summary>
        /// <returns></returns>
        public string Number
        {
            get
            {
                return _Number;
            }
            set
            {
                if (value != _Number)
                {
                    _Number = value;
                    NotifyPropertyChanged("Number");
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

 

開啟 MainPage.xaml 設計模式,修改 TextBlock 的 Text 綁定資料為 Prize 和 Number。

image

 

開啟 MainViewModel.cs 撰寫邏輯。

image

 

在 LoadData() 中,將範例資料刪除,透過 HttpWebRequest 下載統一發票網頁資料。

image

 

在此有個小技巧,我們可以先打方法的名稱,在名稱上,按滑鼠右鍵,選擇 [產生],選擇 [方法] 就會自動幫您產生方法出來。

image

 

接著,在方法中,取得回傳的 Stream 資料。

 

image

 

執行看看程式,看是否能順利取得網頁原始碼資料。

image

 

接著就要進行網頁分析,開啟統一發票網頁,按 F12 開啟開發者工具,透過 [選取元素] 功能,圈選 Table 後,會自動跳至該原始碼位置。

image

 

如果我們要使用 xpath 來解讀它,則需要先使用下列 xpath 先到達上層 table 的位置,再往下取得 HTML 中的內容,因此我們先取得 table 的部分,參考上圖下方的位置,xpath 如下所示 :

/html[1]/body[1]/div[1]/div[2]/div[1]/div[1]/div[1]/table[1]

撰寫程式碼取得對應的 node 資訊,執行程式後,查看取得的資料,是否包含統一發票 table 資訊。

image

 

接著,我們一行行依據 tr 擷取出資料,放到 nodeCollectTr 變數中;執行程式,我們在監看式中查看資料,可以發現 <td class="title"> 對應的是獎項,而 <span class="t18Red"> 對應的是統一發票號碼。

image

 

透過 foreach 抓取一行行資料,並取得 <td class="title"> 和 <span class="t18Red"> 對應的資料,如果資料都抓取出來時,將取得的資料加入 this.Items 中。

image

 

執行程式,可以看到統一發票的資訊被截取與顯示出來。

SNAGHTMLe3efde

 

範例下載

UniformInvoiceApp.rar

 

其他相關資訊

HTML Agility Pack:簡單好用的快速 HTML Parser