C#使用HtmlAgilityPack組件解析html文檔
一、HtmlAgilityPack介紹
參考:
GitHub:https://github.com/zzzprojects/html-agility-pack/releases
官網(wǎng):https://html-agility-pack.net/
https://www.nuget.org/packages/HtmlAgilityPack/
HtmlAgilityPack(以下簡(jiǎn)稱HAP)是一個(gè)基于.Net的、第三方免費(fèi)開(kāi)源的微型類庫(kù),主要用于在服務(wù)器端解析html文檔。
HtmlAgilityPack為網(wǎng)頁(yè)提供了標(biāo)準(zhǔn)的DOM API和XPath導(dǎo)航 。使用WebBrowser和HttpWebRequest下載的網(wǎng)頁(yè)可以用Html Agility Pack來(lái)解析。
Xpath表達(dá)式的參考文檔可見(jiàn):XML基本概念XPath、XSLT與XQuery函數(shù)介紹
二、屬性和方法
HtmlAgilityPack中的HtmlNode類與XmlNode類差不多,HtmlDocument類與XmlDocument類差不多。
1、屬性:
- OwnerDocument:節(jié)點(diǎn)所在的HtmlDocument文檔
- Attributes: 獲取節(jié)點(diǎn)的屬性集合
- ParentNode:獲取該節(jié)點(diǎn)的父節(jié)點(diǎn)
- ChildNodes:獲取子節(jié)點(diǎn)集合(包括文本節(jié)點(diǎn))
- FirstChild: 獲取第一個(gè)子節(jié)點(diǎn)
- LastChild: 獲取最后一個(gè)子節(jié)點(diǎn)
- Id: 獲取該節(jié)點(diǎn)的Id屬性
- Name:Html元素名
- NodeType: 獲取該節(jié)點(diǎn)的節(jié)點(diǎn)類型
- InnerHtml: 獲取該節(jié)點(diǎn)的Html代碼
- InnerText: 獲取該節(jié)點(diǎn)的內(nèi)容,與InnerHtml不同的地方在于它會(huì)過(guò)濾掉Html代碼,而InnerHtml是連Html代碼一起輸出
- OuterHtml: 整個(gè)節(jié)點(diǎn)的代碼
- PreviousSibling: 獲取前一個(gè)兄弟節(jié)點(diǎn)
- NextSibling: 獲取下一個(gè)兄弟節(jié)點(diǎn)
- HasAttributes :判斷該節(jié)點(diǎn)是否含有屬性
- HasChildNodes: 判斷該節(jié)點(diǎn)是否含有子節(jié)點(diǎn)
- HasClosingAttributes : 判斷該節(jié)點(diǎn)的關(guān)閉標(biāo)簽是否含有屬性(</xxx class="xxx">)
- Closed:該節(jié)點(diǎn)是否已關(guān)閉(</xxx>)
- ClosingAttributes在關(guān)閉標(biāo)簽的屬性集合StreamPosition: 該節(jié)點(diǎn)位于整個(gè)Html文檔的字符位置
- XPath: 根據(jù)節(jié)點(diǎn)返回該節(jié)點(diǎn)的XPath
2、方法:
- Load (string path): 從路徑中加載一個(gè)文檔
- SelectNodes (string xpath): 根據(jù)XPath獲取一個(gè)節(jié)點(diǎn)集合
- SelectSingleNode (string xpath): 根據(jù)XPath獲取唯一的一個(gè)節(jié)
- Ancestors (): 返回此元素的所有上級(jí)節(jié)點(diǎn)的集合。
- DescendantNodes (): 獲取所有子代節(jié)點(diǎn)
- Element (string name): 根據(jù)參數(shù)名獲取一個(gè)元素
- Elements (string name): 根據(jù)參數(shù)名獲取匹配的元素集合
- GetAttributeValue(string name, bool def): 幫助方法,用來(lái)獲取此節(jié)點(diǎn)的屬性的值(布爾類型)。如果未找到該屬性,則將返回默認(rèn)值。
- ChildAttributes(string name): 獲取所有子元素的屬性(參數(shù)名要與元素名匹配)
- IsEmptyElement(string name): 確定是否一個(gè)空的元素節(jié)點(diǎn)。
- IsOverlappedClosingElement(string text): 確定是否文本對(duì)應(yīng)于一個(gè)節(jié)點(diǎn)可以保留重疊的結(jié)束標(biāo)記。
- AppendChild(HtmlNode newChild): 將參數(shù)元素追加到為調(diào)用元素的子元素(追加在最后)
- PrependChild(HtmlNode newChild): 將參數(shù)中的元素作為子元素,放在調(diào)用元素的最前面
- Clone(): 本節(jié)點(diǎn)克隆到一個(gè)新的節(jié)點(diǎn)
- CopyFrom(HtmlNode node): 創(chuàng)建重復(fù)的節(jié)點(diǎn)和其下的子樹(shù)。
- CreateNavigator(): 返回的一個(gè)對(duì)于此文檔的XPathNavigator
- CreateNode(string html): 靜態(tài)方法,允許用字符串創(chuàng)建一個(gè)新節(jié)點(diǎn)
- CreateRootNavigator(): 創(chuàng)建一個(gè)根路徑的XPathNavigator
- InsertAfter(HtmlNode newChild, HtmlNode refChild): 將一個(gè)節(jié)點(diǎn)插入到第二個(gè)參數(shù)節(jié)點(diǎn)的后面,與第二個(gè)參數(shù)是兄弟關(guān)系
- InsertBefore(HtmlNode newChild, HtmlNode refChild): 將一個(gè)節(jié)點(diǎn)插入到第二個(gè)參數(shù)節(jié)點(diǎn)的后面,與第二個(gè)參數(shù)是兄弟關(guān)系
- Remove(): 從父集合中移除調(diào)用節(jié)點(diǎn)
- SetAttributeValue(string name, string value): 設(shè)置調(diào)用節(jié)點(diǎn)的屬性
- WriteContentTo(): 將該節(jié)點(diǎn)的所有子級(jí)都保存到一個(gè)字符串中。
- WriteTo(): 將當(dāng)前節(jié)點(diǎn)保存到一個(gè)字符串中。
- Save(string filename): 將HTML文檔保存到指定的路徑
三、用法舉例
下面是幾個(gè)簡(jiǎn)單使用說(shuō)明:
1、獲取網(wǎng)頁(yè)title:
doc.DocumentNode.SelectSingleNode("http://title").InnerText;//XPath中:“//title”表示所有title節(jié)點(diǎn)。SelectSingleNode用于獲取滿足條件的唯一的節(jié)點(diǎn)。
2、獲取所有的超鏈接:
doc.DocumentNode.Descendants("a")
3、獲取name為kw的input,也就是相當(dāng)于getElementsByName():
var kwBox = doc.DocumentNode.SelectSingleNode("http://input[@name='kw']");
示例:
private void Form1_Load(object sender, EventArgs e) { List<Result> list = new List<Result>(); HtmlWeb htmlWeb = new HtmlWeb(); htmlWeb.OverrideEncoding = Encoding.UTF8;//編碼,這里網(wǎng)上有些很多寫(xiě)法都不正確 HtmlAgilityPack.HtmlDocument htmlDoc = htmlWeb.Load(@http://www.cnblogs.com/); //選擇博客園首頁(yè)文章列表 htmlDoc.DocumentNode.SelectNodes("http://div[@id='post_list']/div[@class='post_item']").//雙斜杠“//”表示從跟節(jié)點(diǎn)開(kāi)始查找 AsParallel().ToList().ForEach(ac => { //抓取圖片,因?yàn)橛锌盏模阅米兞看嫫饋?lái) HtmlNode node = ac.SelectSingleNode(".//p[@class='post_item_summary']/a/img"); list.Add(new Result { url = ac.SelectSingleNode(".//a[@class='titlelnk']").Attributes["href"].Value, title = ac.SelectSingleNode(".//a[@class='titlelnk']").InnerText, //圖片如果為空,顯示默認(rèn)圖片 img = node == null ? "http ://www.cnblogs.com//Content/img/avatar.png" : node.Attributes["src"].Value, content = ac.SelectSingleNode(".//p[@class='post_item_summary']").InnerText }); }); foreach (Result item in list) { this.listBox1.Items.Add(item.title); } } /// <summary> /// 頁(yè)面抓取結(jié)果 /// </summary> public class Result { /// <summary> /// 鏈接 /// </summary> public string url { get; set; } /// <summary> /// 標(biāo)題 /// </summary> public string title { get; set; } /// <summary> /// 頭像地址 /// </summary> public string img { get; set; } /// <summary> /// 正文內(nèi)容 /// </summary> public string content { get; set; } }
示例2:下載微軟文檔
using HtmlAgilityPack; using System; using System.Collections.Generic; using System.IO; using System.Text; namespace ConsoleApp4 { internal class Program { private static void Main(string[] args) { //網(wǎng)頁(yè)地址: string Url = "https://docs.microsoft.com/zh-cn/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application"; List<string> list = new List<string>(); ; HtmlWeb htmlWeb = new HtmlWeb(); htmlWeb.OverrideEncoding = Encoding.UTF8; HtmlDocument htmlDoc = htmlWeb.Load(Url); HtmlNode node = htmlDoc.DocumentNode.SelectSingleNode("http://main[@id='main']"); //去掉英文翻譯 var a = node.SelectNodes("http://span[@class='sxs-lookup']"); foreach (HtmlNode b in a) { b.Remove(); } string src = ""; //圖片相對(duì)路徑改成絕對(duì)路徑 var imgNode = node.SelectNodes("http://img[@data-linktype='relative-path']"); foreach (HtmlNode node1 in imgNode) { src = node1.GetAttributeValue("src", ""); var url = new Uri(htmlWeb.ResponseUri, src); node1.SetAttributeValue("src", url.AbsoluteUri); } //鏈接路徑轉(zhuǎn)換 var hrefNode = node.SelectNodes("http://a[@data-linktype='relative-path']|//a[@data-linktype='absolute-path']"); foreach (HtmlNode node1 in hrefNode) { src = node1.GetAttributeValue("href", ""); var url = new Uri(htmlWeb.ResponseUri, src); node1.SetAttributeValue("href", url.AbsoluteUri); } //找到所有的H2標(biāo)簽,然后加上順序。 var h2Node = node.SelectNodes("http://h2"); var arr = new string[] { "一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二", "十三", "十四", "十五", "十六", "十七", "十八", "十九", "二十" }; if (h2Node != null) { for (int i = 0; i < h2Node.Count; i++) { h2Node[i].InnerHtml = arr[i] + "、" + h2Node[i].InnerHtml; //找到所有的H3標(biāo)簽,然后加上順序。 var h3Node = h2Node[i].SelectNodes("following-sibling::h2|following-sibling::h3"); if (h3Node is null) break; for (int j = 0; j < h3Node.Count; j++) { if (h3Node[j].Name == "h2") break; else h3Node[j].InnerHtml = (j + 1) + "、" + h3Node[j].InnerHtml; } } } HtmlNode myNOde = htmlDoc.CreateElement("div"); //去掉前面無(wú)用的部分 var OK = node.SelectNodes("nav[1]/following-sibling::*"); myNOde.AppendChildren(OK); //添加原文連接: HtmlNode nodeOriUrl = htmlDoc.CreateElement("p"); nodeOriUrl.InnerHtml = "原文:<a href='" + htmlWeb.ResponseUri + "'>" + htmlWeb.ResponseUri + "</a>"; myNOde.PrependChild(nodeOriUrl); //寫(xiě)入到本地文件 TextWriter wr = new StreamWriter(@"aa.html"); myNOde.WriteTo(wr); wr.Close(); } } }
四、Fizzler.Systems.HtmlAgilityPack:
Hazz為HTMLAgilityPack實(shí)現(xiàn)CSS選擇器。它基于Fizzler,一個(gè)通用的CSS選擇器解析器和生成器庫(kù)。
Hazz以前稱為Fizzler.Systems.HtmlAgilityPack。
// Load the document using HTMLAgilityPack as normal var html = new HtmlDocument(); html.LoadHtml(@" <html> <head></head> <body> <div> <p class='content'>Fizzler</p> <p>CSS Selector Engine</p></div> </body> </html>"); // Fizzler for HtmlAgilityPack is implemented as the // QuerySelectorAll extension method on HtmlNode var document = html.DocumentNode; // yields: [<p class="content">Fizzler</p>] document.QuerySelectorAll(".content"); // yields: [<p class="content">Fizzler</p>,<p>CSS Selector Engine</p>] document.QuerySelectorAll("p"); // yields empty sequence document.QuerySelectorAll("body>p"); // yields [<p class="content">Fizzler</p>,<p>CSS Selector Engine</p>] document.QuerySelectorAll("body p"); // yields [<p class="content">Fizzler</p>] document.QuerySelectorAll("p:first-child");
到此這篇關(guān)于C#使用HtmlAgilityPack組件解析html文檔的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
字符串和十六進(jìn)制之間的轉(zhuǎn)換方法實(shí)例
這篇文章介紹了字符串和十六進(jìn)制之間的轉(zhuǎn)換方法實(shí)例,有需要的朋友可以參考一下2013-11-11DevExpress實(shí)現(xiàn)TreeList按條件隱藏節(jié)點(diǎn)CheckBox的方法
這篇文章主要介紹了DevExpress實(shí)現(xiàn)TreeList按條件隱藏節(jié)點(diǎn)CheckBox的方法,需要的朋友可以參考下2014-08-08C#使用FileInfo和DirectoryInfo類來(lái)執(zhí)行文件和文件夾操作
System.IO.FileInfo?和?System.IO.DirectoryInfo?是C#中用于操作文件和文件夾的類,它們提供了許多有用的方法和屬性來(lái)管理文件和文件夾,這篇文章主要介紹了C#使用FileInfo和DirectoryInfo類來(lái)執(zhí)行文件和文件夾操作,需要的朋友可以參考下2023-08-08深入淺析C#?11?對(duì)?ref?和?struct?的改進(jìn)
這篇文章主要介紹了C#?11?對(duì)?ref?和?struct?的改進(jìn),有了這些基礎(chǔ)設(shè)施,開(kāi)發(fā)者們將能輕松使用安全的方式來(lái)編寫(xiě)沒(méi)有任何堆內(nèi)存開(kāi)銷的高性能代碼,需要的朋友可以參考下2022-04-04