在先前的文章我們已經學習到透過 WebClient 的方式下載 RSS 資料,解析後呈現在畫面上。然而,不是每個網站資料都提供開放格式讓你可以直接抓取與分析資料,例如說想要抓取統一發票的資料,我們可以到以下網址抓取,但無法直接取得統一發票資料。
http://invoice.etax.nat.gov.tw/
我們可以透過 Html Agility Pack 做網頁分析與擷取資料,透過 xpath 的方式,擷取出想要的資料。
本文刊載於
http://www.dotblogs.com.tw/chou/archive/2013/09/12/118335.aspx
在這篇文章您可以學到:
程式撰寫
將 Html Agility Pack 加入專案,在專案上按滑鼠右鍵,選擇 [管理 NuGet 套件]。
搜尋關鍵字 Html Agility Pack,找出 Html Agility Pack 後進行 [安裝]。
安裝後,還需要額外加入參考 System.Xml.Xpath.dll,請參考下圖說明,加入參考,我是新增 Window Phone 7.1 專案,因此加入的路徑是
C:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Libraries\Client\System.Xml.XPath.dll
透過瀏覽,加入參考 System.Xml.Xpath.dll
如果出現警告訊息,請按 [是]。
確認參考都有加入。
首先,針對 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。
開啟 MainViewModel.cs 撰寫邏輯。
在 LoadData() 中,將範例資料刪除,透過 HttpWebRequest 下載統一發票網頁資料。
在此有個小技巧,我們可以先打方法的名稱,在名稱上,按滑鼠右鍵,選擇 [產生],選擇 [方法] 就會自動幫您產生方法出來。
接著,在方法中,取得回傳的 Stream 資料。
執行看看程式,看是否能順利取得網頁原始碼資料。
接著就要進行網頁分析,開啟統一發票網頁,按 F12 開啟開發者工具,透過 [選取元素] 功能,圈選 Table 後,會自動跳至該原始碼位置。
如果我們要使用 xpath 來解讀它,則需要先使用下列 xpath 先到達上層 table 的位置,再往下取得 HTML 中的內容,因此我們先取得 table 的部分,參考上圖下方的位置,xpath 如下所示 :
/html[1]/body[1]/div[1]/div[2]/div[1]/div[1]/div[1]/table[1]
撰寫程式碼取得對應的 node 資訊,執行程式後,查看取得的資料,是否包含統一發票 table 資訊。
接著,我們一行行依據 tr 擷取出資料,放到 nodeCollectTr 變數中;執行程式,我們在監看式中查看資料,可以發現 <td class="title"> 對應的是獎項,而 <span class="t18Red"> 對應的是統一發票號碼。
透過 foreach 抓取一行行資料,並取得 <td class="title"> 和 <span class="t18Red"> 對應的資料,如果資料都抓取出來時,將取得的資料加入 this.Items 中。
執行程式,可以看到統一發票的資訊被截取與顯示出來。