c# 使用HtmlAgilityPack解析Html

HtmlAgilityPack 是一个开源的快速解析Html的C#类库。简单理解,它可以像解析Xml一样,将Html根据XPATH转化为一个个Node节点,并支持调整节点以及节点的各种属性。

传送门:官网 | Github源码

多种方式加载Html

主要加载方式有3类:从网络链接加载、从字符串文本中加载、从文件加载

var doc = new HtmlDocument();
//直接通过url加载
doc = new HtmlWeb().Load("https://www.baidu.com/");
//通过字符串加载
doc.LoadHtml(result);
//通过html文件加载 可指定编码方式
doc.Load(@"c://index.html",Encoding.UTF8)

HtmlNode常用方法

使用SelectNodes()和SelectSingleNode()方法(类似解析XML格式数据的XmlDocument)来获取的目标节点,分别对应HtmlNodeCollection和HtmlNode两个类。

"//"表示从根节点开始查找,两个斜杠"//"表示查找所有childnodes;一个斜杠"/"表示只查找第一层的childnodes(即不查找grandchild);点斜杠"./"表示从当前结点而不是根结点开始查找(只在xpath最开始出现)

注意:

id class 属性匹配大小写敏感
xpath匹配下标从1开始

1. 通过属性和路径匹配来选择对应的节点

var node = doc.DocumentNode;

//选择不包含class属性的div节点
var result = node.SelectNodes(".//div[not(@class)]");

//选择不包含class和id属性的div节点
var result = node.SelectNodes(".//div[not(@class) and not(@id)]");

//选择class中包含"expire"的span节点
var result = node.SelectNodes(".//span[contains(@class,'expire')]");

//选择class中不包含"expire"的span节点
var result = node.SelectNodes(".//span[not(contains(@class,'expire'))]");

//选择class="expire"的span节点
var result = node.SelectNodes(".//span[@class='expire']");

//选择id="expire"的div节点下第一个div节点
var result = node.SelectSingleNode(".//div[@id='expire']/div[1]");

2. 获取节点文本内容

根据需求不同,通过不同的方式来获取相应的文本内容。
OuterHtml:返回包含当前节点在内的所有Html
InnerHtml:返回当前节点内所有子节点Html
InnerText:返回当前节点内去除所有Html后的文本内容

<div id="title">
  <p>
   <a class="MainTitle" href="https://www.cnblogs.com/cplemom/" rel="external nofollow" rel="external nofollow" rel="external nofollow" >傅小灰</a>
  </p>
</div>

以上面的Html为例

var node= doc.DocumentNode.SelectSingleNode("//div[@id='title'/p]");

node.OuterHtml; //返回结果:<p><a class="MainTitle"href="https://www.cnblogs.com/cplemom/" rel="external nofollow" rel="external nofollow" rel="external nofollow" >傅小灰</a></p>

node.InnerHtml; //返回结果:<a class="MainTitle"href="https://www.cnblogs.com/cplemom/" rel="external nofollow" rel="external nofollow" rel="external nofollow" >傅小灰</a>

node.InnerText; //返回结果:傅小灰

3. 获取/修改节点属性值

以上面的Html举例,我们获取到了a标签为node节点。我们想要获取a标签指向的链接地址,并修改为我们设定的地址。这里以href属性举例,同样可以用在class/src/id等属性上。

var node= doc.DocumentNode.SelectSingleNode("//div[@id='title'/p/a]");

//第二个参数为找不到对应属性时返回的默认值
var url = node.GetAttributeValue("href", "");//返回结果:https://www.cnblogs.com/cplemom/

//设置属性值
node.SetAttributeValue("href", "http://www.cplemom.com/");

//获取所有属性值
var list = node.Attributes.ToList();

4. 删除/替换节点

继续以上面的Html举例,我们获取到了a标签为node节点。
对于我们不需要的内容,我们只需要调用节点Remove方法即可。

var node= doc.DocumentNode.SelectSingleNode("//div[@id='title'/p/a]");

node.Remove();//删除节点

一个很常见的场景就是我们需要移除a标签,但是要在html上下文中保留a标签的文本。
PS : a标签内的文本在HtmlDocument中其实是一个text类型的node节点。所以我们可以通过删除a标签,保留text标签的方式来完成目标。

node.ParentNode.RemoveChild(node,true); 

true表示留下a标签的子节点只删除a标签,在这里就表示保留下“傅小灰”text节点; false表示将此结点连同所有子节点一起删除。

换个角度思考下,当前node节点代表的是单个a标签,那么如果p标签下存在多个a标签需要处理,或者node节点指向的就是p标签呢?当然,我们可以通过获取所有a标签然后循环处理的方式来实现,但是还有没有别的更好的处理方式呢?

这里提供一个思路,获取所有的文本内容,新建为一个text节点,然后替换掉当前节点。

node.ParentNode.ReplaceChild(HtmlNode.CreateNode(item.InnerText), node);

几个常见使用场景和解决方案

1. 获取所有的img标签

//通过Descendants获取所有的子后代节点中的img标签
var list = node.Descendants("img");

//通过Xpath匹配获取所有img标签
var list = node.SelectNodes("//img");

2. 通过url访问时需要携带cookie等验证信息

有些页面需要携带验证信息才能访问,比如用户中心,订单列表等,这时候直接通过HtmlWeb类获取html会被拒绝。有个简单的方式就是通过HttpClient请求到对应的html内容,再使用HtmlDocument加载。其实HtmlWeb说白了也是封装的HttpWebRequest进行网络请求的,所以暴露一个委托给外部用以修改请求上下文。

var web = new HtmlWeb();
web.PreRequest = new HtmlWeb.PreRequestHandler(GetRequest);
var node = web.Load("https://www.cplemom.com/");

public static bool GetRequest(HttpWebRequest req)
{
  req.Headers.Add("Host", "www.cplemom.com");
	req.Headers.Add("Cookie", "xxxxxxxxxxxxx");
  return true;
}

总结

用到现在,个人感觉上面的方法已经可以实现90%以上的的Html解析相关需求了,更多方便快捷的方法还是到官网的API文档进行了解吧。

以上就是c# 使用HtmlAgilityPack解析Html的详细内容,更多关于c# HtmlAgilityPack解析Html的资料请关注我们其它相关文章!

(0)

相关推荐

  • c#使用htmlagilitypack解析html格式字符串

    使用方法: 1.引用HtmlAgilityPack.dll文件 2.引用命名空间: 复制代码 代码如下: using HtmlAgilityPack; 3.调用 复制代码 代码如下: static void Main(string[] args)        {            string html = GetHtml("http://www.jb51.net");            HtmlDocument doc = new HtmlDocument();      

  • C#抓取网页数据 解析标题描述图片等信息 去除HTML标签

    一.首先将网页内容整个抓取下来,数据放在byte[]中(网络上传输时形式是byte),进一步转化为String,以便于对其操作,实例如下: 复制代码 代码如下: private static string GetPageData(string url) {     if (url == null || url.Trim() == "")         return null;     WebClient wc = new WebClient();     wc.Credentials

  • c#使用nsoup解析html乱码解决方法分享 nsoup教程

    下载地址:http://nsoup.codeplex.com/ 简单用法如下: 复制代码 代码如下: NSoup.Nodes.Document doc = NSoup.NSoupClient.Parse(HtmlString); 处理网络上的页面: 复制代码 代码如下: NSoup.Nodes.Document doc = NSoup.NSoupClient.Connect("http://www.jb51.net/").Get(); 但是遗憾的是NSoup默认的编码是UTF-8,处理

  • C#正则过滤HTML标签并保留指定标签的方法

    本文实例讲述了C#正则过滤HTML标签并保留指定标签的方法.分享给大家供大家参考,具体如下: 这边主要看到一个过滤的功能: public static string FilterHtmlTag(string s) { //<...>标记正则表达式 return Regex.Replace(s, @"<[^>]*>", delegate(Match match) { string v = match.ToString(); //图片,<p>,&l

  • C#基于正则表达式抓取a标签链接和innerhtml的方法

    本文实例讲述了C#基于正则表达式抓取a标签链接和innerhtml的方法.分享给大家供大家参考,具体如下: //读取网页html string text = File.ReadAllText(Environment.CurrentDirectory + "//test.txt", Encoding.GetEncoding("gb2312")); string prttern = "<a(\\s+(href=\"(?<url>([

  • C#下解析HTML的两种方法介绍

    在搜索引擎的开发中,我们需要对Html进行解析.本文介绍C#解析HTML的两种方法.AD: 在搜索引擎的开发中,我们需要对网页的Html内容进行检索,难免的就需要对Html进行解析.拆分每一个节点并且获取节点间的内容.此文介绍两种C#解析Html的方法. C#解析Html的第一种方法:用System.Net.WebClient下载Web Page存到本地文件或者String中,用正则表达式来分析.这个方法可以用在Web Crawler等需要分析很多Web Page的应用中.估计这也是大家最直接,

  • C# 使用 WebBrowser 实现 HTML 转图片功能的示例代码

    在 .NET 平台上,我们有多种方式可以将一段 HTML 文本转换为一张图片:HTML Renderer.SelectPdf .Aspose.Html等. 在 WinForm 程序中,每一个 System.Windows.Forms.Control 的派生类型均包含一个名为 DrawToBitmap 的方法,该方法可以将控件绘制到一张图片上.WebBrowser 具备显示 HTML 的功能,又因为其从 Control 类型派生,所以包含 DrawToBitmap 方法.我们只需将要在 WebBr

  • 利用C#代码将html样式文件与Word文档互换的方法

    一.C#代码将html样式文件转为Word文档 首先有个这样的需求,将以下网页内容下载为Word文件. html代码: <div class="modal-body"> <div style="height:600px;width:550px; margin:0 auto;"> <table style="border-collapse:separate;border-spacing:10px;width: 100%"

  • 通过C#实现发送自定义的html格式邮件

    要发送HTML格式邮件,需要设置MailMessage对象的IsBodyHtml属性,设置为true. 类MailMessage在命名空间System.Net.Mail下. using System.Net.Mail; 发送HTML格式的邮件在HoverTreeTop项目中已经实现,并发送成功. 需依赖于HoverTreeFrame项目的HoverTreeEmail类. 方法为: 复制代码 代码如下: public static string HoverTreeSendEmail(string

  • C#自写的一个HTML解析类(类似XElement语法)

    功能: 1.轻松获取指元素HTML元素. 2.可以根据属性标签进行筛选 3.返回的都是Llist强类型无需转换 用过XElement的都知道 用来解析XML非常的方便,但是对于HTML的格式多样化实在是没办法兼容. 所以我就写了这么一个类似XElement的 XHTMLElement 用法: string filePath = Server.MapPath("~/file/test.htm"); //获取HTML代码 string mailBody = FileHelper.FileT

随机推荐