这是个很好的的东西,以前做Html解析都是在用htmlparser,用的虽然顺手,但解析速度较慢,碰巧今天找到了这个,就拿过来试,一切出乎意料,非常爽,推荐给各位使用。
下面是一些简单的使用技巧,希望对大家有用,我个人也是个学习过程。
Why Html Agility Pack? (以下简称HAP)
.Net下解析HTML文件有很多种选择,包括微软自己也提供MSHTML用于manipulate HTML文件。但是,经过我一段时间的搜索,Html Agility Pack浮出水面:它是Stackoverflow网站上推荐最多的C# HTML解析器。HAP开源,易用,解析速度快。
How to use HAP?
1. 下载http://htmlagilitypack.codeplex.com/
2. 解压
3. 在Visual Studio Solution里,右击project ->add reference ->选择解压文件夹里的HTMLAgilityPack.dll ->确定
4. 代码头部加入 using HtmlAgilityPack;
Done!
view plaincopy to clipboardprint?
HtmlWeb webClient = new HtmlWeb(); HtmlDocument doc = webClient.Load("http://xxx"); HtmlNodeCollection hrefList = doc.DocumentNode.SelectNodes("http://www.360doc.cn/article//a[@href]"); if (hrefList != null) { foreach (HtmlNode href in hrefList) { HtmlAttribute att = href.Attributes["href"]; doSomething(att.Value); } }Q: 如何根据ID选择HTML结点?
A: 利用@id="xxx', e.g.,
view plaincopy to clipboardprint?
HtmlNode bugSum = doc.DocumentNode.SelectSingleNode("http://h2[@id="summary']");Q: 如何得到结点的文字内容或Html内容?
view plaincopy to clipboardprint?
node.InnerText.Trim() node.InnerHtml node.OuterHtmlQ: 如何在html树结构下查找结点?
A: 比如从根节点查找id=container的div下的第一个table:
view plaincopy to clipboardprint?
HtmlNode table = doc.DocumentNode.SelectSingleNode("http://div[@id="container']/table[1]");注意路径里"http://"表示从根节点开始查找,两个斜杠‘//’表示查找所有childnodes;一个斜杠'/'表示只查找第一层的childnodes(即不查找grandchild);点斜杠"http://www.360doc.cn/article/"表示从当前结点而不是根结点开始查找。接上一行代码,比如要查找table所有直接子结点的tr:
view plaincopy to clipboardprint?
HtmlNodeCollection tr = table.SelectNodes("http://www.360doc.cn/article/tr");Q: 如何得到结点的ID?
A: 很简单: node.ID
Q: 如果一段html存在字符串里,是否可以用Html Agility Pack进行处理?
A:可以,先将字符串load进来,之后的处理方法一样:
view plaincopy to clipboardprint?
//load the original html string html = "some html stuff" HtmlDocument doc = new HtmlDocument(); doc.LoadHtml(@html);Q: 我对load进来的html进行了一些处理,比如改变了一些结点内容,删除了一些结点什么的,为什么结果却没有变化?
A: 也许你忘记save你对html的改变了,假设html存在字符串中:
view plaincopy to clipboardprint?
//load the original html string html = "some html stuff" HtmlDocument doc = new HtmlDocument(); doc.LoadHtml(@html); //make some changes doSomething(); //save the change var sb = new StringBuilder(); using (var writer = new StringWriter(sb)) { doc.Save(writer); }Q: 如何去掉外层的html tag只留下内容?
A: 用remove方法。假设结点ABCD,你想留下ABCD而不要,那你需要先得到这个Html结点,假设叫link:
view plaincopy to clipboardprint?
link.ParentNode.RemoveChild(link,true);参数true表示留下grandchild,在这里即内容ABCD; false表示将此结点连同其grandchilds一起删除。
规则有很多,网上提供了源代码,可以研究一下,还有源代码有乱码问题,是字符集的问题,只需要写一个方法来自动判断就可以解决了