[Windows Phone]學習使用HttpAgilityPack
想要從網路上抓資料,除了可以使用httpwebrequest之外,還有一個不錯用的工具就是HttpAgilityPack,
HttpAgilityPack是以節點的方式抓取資料,在某些情況下還是必須將字串切割擷取資料。
以下文字有點多,若覺得很繁瑣可以直接拉至下方有整段code。
這裡拿「國立自然科學博物館的當期特展」的資料為例。
1.請到NuGet安裝「HtmlAgilityPack」。
2.到「參考」裡加入「System.Xml.XPath」,路徑為「C:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Libraries\Client」
這裡是裝在「32位元」的位置。若是「64位元」則為「C:\Program Files\~」
要引用「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基础类介绍及运用
若有觀念錯誤、內容錯誤,勞請告知。 謝謝。
若要轉載請註明出處,謝謝。