HtmlAgilityPack是一個專門用來解析Html的庫,它可以使用xml的方式來解析html。
有人說了,html本身不就是xml?是的,html就是xml,但是html很寬鬆,沒有關閉的節點也可以用,還有一些其他的內容比如js夾雜在裡面。如果直接使用xml解析庫的話9成會報錯的。
而HtmlAgilityPack會去處理這些問題,把Html轉成一個接近標準的xml來供我們使用。
網上關於HtmlAgilityPack的介紹其實很多,而且用法其實就那麼幾句話。
var doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html);
var root = doc.DocumentNode;
這個也沒啥好說的,主要就是doc.LoadHtml(html);
這裡有個過載是doc.Load()
,裡面可以直接放url,也可以放Stream
。
我們這裡使用LoadHtml
直接載入html內容主要是因為我們的html拿的時候可能還需要別的東西,需要另行獲取。
最後的var root = doc.DocumentNode;
這個root就是<html>
節點,整個html的根目錄。
然後很多文章的說法就是我們要獲取Node,即使用
var node =root.SelectSingleNode("xpath");
這樣肯定是沒問題的,然後我們如果要獲得它的屬性,就可以拿這個Node的node.GetAttributeValue("name", 預設值);
獲取內容。
比如我們要獲取id
為test
的a
標籤的href
,我們可以寫個例子
var doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html);
var root = doc.DocumentNode;
var node =root.SelectSingleNode("//a[@id='test']");
var href = GetAttributeValue("href", "");
這樣我們就能獲取到href了。是不是很簡單?
上面的例子看起來很好,但是有個比較麻煩的問題,就是有時候我們想直接獲取屬性值。比如我有一個這樣的xpath //a[@id='test']/@href
,如果我們還用上面的程式碼套進去。
var doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html);
var root = doc.DocumentNode;
var node =root.SelectSingleNode("//a[@id='test']/@href");
我們的node是不是就是href的值呢?經過測試,不是的,這裡的node還是那個a。
所以我們無法直接這樣來獲取。
經過一番查詢,發現HtmlAgilityPack提供了一個HtmlNodeNavigator來完成這個需求。
var doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html);
var root = doc.DocumentNode;
HtmlNodeNavigator navigator = (HtmlNodeNavigator)root.CreateNavigator();
var node = navigator.SelectSingleNode("//a[@id='test']/@href");
var href = node.Value;
這裡我們可以獲取到一個HtmlNodeNavigator的node,這個node不是指向a
標籤,而是直接指向href
屬性,所以我們直接拿node.Value
就可以獲取到真正的href
的值了