[Windows Phone]學習使用HttpAgilityPack

  • 4419
  • 0
  • 2014-01-22

[Windows Phone]學習使用HttpAgilityPack

 

想要從網路上抓資料,除了可以使用httpwebrequest之外,還有一個不錯用的工具就是HttpAgilityPack,

HttpAgilityPack是以節點的方式抓取資料,在某些情況下還是必須將字串切割擷取資料。

 

 

以下文字有點多,若覺得很繁瑣可以直接拉至下方有整段code。

 

 

這裡拿「國立自然科學博物館的當期特展」的資料為例。

 

1.請到NuGet安裝「HtmlAgilityPack」。

1

 

 

 

2.到「參考」裡加入「System.Xml.XPath」,路徑為「C:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Libraries\Client」

這裡是裝在「32位元」的位置。若是「64位元」則為「C:\Program Files\~」

2

要引用「System.Xml.XPath」的原因是,HttpAgilityPack是採用XPath的語言來取得HTML的標籤。

有關XPath的介紹,請點我

 

 

3.再來到cs的mainpage打入

 

 

   1: HtmlWeb client = new HtmlWeb();//宣告HtmlWeb
   2: client.LoadCompleted += client_loadcomleted;//註冊資料解析之事件
   3: client.LoadAsync("http://www.nmns.edu.tw/ch/exhibit/exhibits.htm");//載入要解析之網址。

 

 

4.之後再剛剛註冊的事件裡打入

   1: if (e.Error == null)//判斷是否載入成功
   2: {
   3:  
   4: }

 

然後在「If」取得網頁的內文

   1: HtmlDocument doc = e.Document;//取得解析網頁之內文(含標籤)

 

之後判斷是否有取到內文。

   1: if (doc != null)
   2: {
   3:  
   4: }

 

再來開始找出所需要的路徑

   1: HtmlNodeCollection tr1 = doc.DocumentNode.SelectNodes(@"//table[@cellspacing='6']/tbody/tr/td[@width='25%']/p");//選擇的路徑

這邊直接搜尋table的標籤,其屬性抓取第一個即可,寫法是table[@cellspacing='6'],

其要抓取的屬性外面須加上「[]」,而裡面的屬性前面需加上「@」。

 

 

「tr1」所抓取的是一集合,需要將裡面的資料一一取出,這裡使用「foreach」抓取。

   1: foreach (HtmlNode td in tr1)//tr1中有很多筆<td width=25%>,用foreach將資料一一找出來
   2: {
   3:  
   4: }

 

 

在「foreach」裡面,要取得特展的圖片、詳細網頁之網址、場地位置、日期還有名稱。

   1: HtmlNode img = td.SelectSingleNode(@"img");//取得該特展之圖片標籤
   2: HtmlNode href = td.SelectSingleNode(@"a");//取得該特展之連結標籤
   3:  
   4: string src = img.GetAttributeValue("src", "");//將該特展的圖片屬性存入src
   5: string link = href.GetAttributeValue("href", "");//將該特展的詳細網頁網址屬性存入link
   6:  
   7: string imgsource = "http://www.nmns.edu.tw" + src; //取得該圖片之連結網址並存入imgsource
   8: BitmapImage bitmap = new BitmapImage(new Uri(imgsource));//宣告並建立BitmapImage
   9: image.Source = bitmap;//Image物件來源設定
  10:  
  11: //抓取場地的code
  12: int TotalNum = td.InnerHtml.ToString().Length;//取得所有字數長度
  13: int PositionNum = td.InnerHtml.ToString().LastIndexOf("<br>");//取得最後一個BR的位置
  14: string Position = td.InnerHtml.ToString().Substring(PositionNum + 4, TotalNum - (PositionNum + 4));//擷取場地的內文
  15: //抓取場地的code (End)
  16:  
  17: //抓日期的code
  18: string after = td.InnerHtml.ToString().Substring(0, PositionNum);//把最後一個BR去掉,即是剛剛所抓取的「場地」
  19: int AfterNum = after.Length;//擷取後的總長度
  20: int DateNum = after.ToString().LastIndexOf("<br>");//取得最後一個BR的位置
  21: string Date = after.ToString().Substring(DateNum + 4, AfterNum - (DateNum + 4));//擷取日期的內文
  22: //抓日期的code (End)
  23:  
  24: //抓名稱的code
  25: string name = href.InnerText;//取得連結標籤的內文,即是特展名稱
  26: //抓名稱的code (End)

 

 

 

整個事件的程式碼為

   1: if (e.Error == null)//判斷是否載入成功
   2: {
   3:     HtmlDocument doc = e.Document;//取得解析網頁之內文(含標籤)
   4:     if (doc != null)
   5:     {
   6:         HtmlNodeCollection tr1 = doc.DocumentNode.SelectNodes(@"//table[@cellspacing='6']/tbody/tr/td[@width='25%']/p");//選擇的路徑
   7:         foreach (HtmlNode td in tr1)//tr1中有很多筆<td width=25%>,用foreach將資料一一找出來
   8:         {
   9:             HtmlNode img = td.SelectSingleNode(@"img");//取得該特展之圖片標籤
  10:             HtmlNode href = td.SelectSingleNode(@"a");//取得該特展之連結標籤
  11:  
  12:             string src = img.GetAttributeValue("src", "");//將該特展的圖片屬性存入src
  13:             string link = href.GetAttributeValue("href", "");//將該特展的詳細網頁網址屬性存入link
  14:  
  15:             string imgsource = "http://www.nmns.edu.tw" + src; //取得該圖片之連結網址並存入imgsource
  16:             BitmapImage bitmap = new BitmapImage(new Uri(imgsource));//宣告並建立BitmapImage
  17:             image.Source = bitmap;//Image物件來源設定
  18:  
  19:             //抓取場地的code
  20:             int TotalNum = td.InnerHtml.ToString().Length;//取得所有字數長度
  21:             int PositionNum = td.InnerHtml.ToString().LastIndexOf("<br>");//取得最後一個BR的位置
  22:             string Position = td.InnerHtml.ToString().Substring(PositionNum + 4, TotalNum - (PositionNum + 4));//擷取場地的內文
  23:             //抓取場地的code (End)
  24:  
  25:             //抓日期的code
  26:             string after = td.InnerHtml.ToString().Substring(0, PositionNum);//把最後一個BR去掉,即是剛剛所抓取的「場地」
  27:             int AfterNum = after.Length;//擷取後的總長度
  28:             int DateNum = after.ToString().LastIndexOf("<br>");//取得最後一個BR的位置
  29:             string Date = after.ToString().Substring(DateNum + 4, AfterNum - (DateNum + 4));//擷取日期的內文
  30:             //抓日期的code (End)
  31:  
  32:             //抓名稱的code
  33:             string name = href.InnerText;//取得連結標籤的內文,即是特展名稱
  34:             //抓名稱的code (End)
  35:         }
  36:     }
  37: }

 

 

 

 

 

 

 

 

 

所有程式碼為

   1: public MainPage()
   2: {
   3:     InitializeComponent();
   4:     HtmlWeb client = new HtmlWeb();//宣告HtmlWeb
   5:     client.LoadCompleted += client_loadcomleted;//註冊資料解析之事件
   6:     client.LoadAsync("http://www.nmns.edu.tw/ch/exhibit/exhibits.htm");//載入要解析之網址。
   7: }
   8:  
   9: private void client_loadcomleted(object sender, HtmlDocumentLoadCompleted e)
  10: {
  11:     if (e.Error == null)//判斷是否載入成功
  12:     {
  13:         HtmlDocument doc = e.Document;//取得解析網頁之內文(含標籤)
  14:         if (doc != null)
  15:         {
  16:             HtmlNodeCollection tr1 = doc.DocumentNode.SelectNodes(@"//table[@cellspacing='6']/tbody/tr/td[@width='25%']/p");//選擇的路徑
  17:             foreach (HtmlNode td in tr1)//tr1中有很多筆<td width=25%>,用foreach將資料一一找出來
  18:             {
  19:                 HtmlNode img = td.SelectSingleNode(@"img");//取得該特展之圖片標籤
  20:                 HtmlNode href = td.SelectSingleNode(@"a");//取得該特展之連結標籤
  21:  
  22:                 string src = img.GetAttributeValue("src", "");//將該特展的圖片屬性存入src
  23:                 string link = href.GetAttributeValue("href", "");//將該特展的詳細網頁網址屬性存入link
  24:  
  25:                 string imgsource = "http://www.nmns.edu.tw" + src; //取得該圖片之連結網址並存入imgsource
  26:                 BitmapImage bitmap = new BitmapImage(new Uri(imgsource));//宣告並建立BitmapImage
  27:                 image.Source = bitmap;//Image物件來源設定
  28:  
  29:                 //抓取場地的code
  30:                 int TotalNum = td.InnerHtml.ToString().Length;//取得所有字數長度
  31:                 int PositionNum = td.InnerHtml.ToString().LastIndexOf("<br>");//取得最後一個BR的位置
  32:                 string Position = td.InnerHtml.ToString().Substring(PositionNum + 4, TotalNum - (PositionNum + 4));//擷取場地的內文
  33:                 //抓取場地的code (End)
  34:  
  35:                 //抓日期的code
  36:                 string after = td.InnerHtml.ToString().Substring(0, PositionNum);//把最後一個BR去掉,即是剛剛所抓取的「場地」
  37:                 int AfterNum = after.Length;//擷取後的總長度
  38:                 int DateNum = after.ToString().LastIndexOf("<br>");//取得最後一個BR的位置
  39:                 string Date = after.ToString().Substring(DateNum + 4, AfterNum - (DateNum + 4));//擷取日期的內文
  40:                 //抓日期的code (End)
  41:  
  42:                 //抓名稱的code
  43:                 string name = href.InnerText;//取得連結標籤的內文,即是特展名稱
  44:                 //抓名稱的code (End)
  45:             }
  46:         }
  47:     }
  48:     else
  49:     {
  50:         MessageBox.Show("無法連線,請確定是否有連上網際網路");
  51:     }
  52: } 
  53: }

 

 

Reference

[Windows Phone/C#] C# 網頁擷取資料 解析網頁標籤(HTML Parser )API -HTML Agility Pack 以Windows Phone 8 為例

HTML Agility Pack

Html Agility Pack基础类介绍及运用

 

 

若有觀念錯誤、內容錯誤,勞請告知。 謝謝。

若要轉載請註明出處,謝謝。