一、概述

Html Agility Pack 简称HAP,是一个强大而灵活的解析Html DOM的.Net类库。

二、官方链接

官网:http://html-agility-pack.net/

NuGet: https://www.nuget.org/packages/HtmlAgilityPack/

Github:https://github.com/zzzprojects/html-agility-pack

三、用法及示例

1、解析前需要加载资源,有四种方式载入:

(1) File

var path = @"D:\test.html";

var doc = new HtmlDocument();
doc.Load(path);

以上的path是自己的文件路径,这样html被加载到了Doc之后就可以解析了。

(2) String

var html = @"<!DOCTYPE html>
<html>
<body>
<h1>This is <b>bold</b> heading</h1>
<p>This is <u>underlined</u> paragraph</p>
<h2>This is <i>italic</i> heading</h2>
</body>
</html> "; var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(html); var htmlBody = htmlDoc.DocumentNode.SelectSingleNode("//body");

 以上的html是一个html格式的字符串。通过LoadHtml加载到了htmlDoc。在爬虫过程中通过url获取的html内容字符串后,就可以通过这种方式加载。

(3) Web

var html = @"http://html-agility-pack.net/";

HtmlWeb web = new HtmlWeb();

var htmlDoc = web.Load(html);

这个方法则是直接通过url加载。如果是只有url,则较之前一种方法更为简单,不需要再另写通过url获取html内容字符串的方法。

(4) Browser

string url = "http://html-agility-pack/from-browser";

var web1 = new HtmlWeb();
var doc1 = web1.LoadFromBrowser(url, o =>
{
var webBrowser = (WebBrowser) o; // WAIT until the dynamic text is set
return !string.IsNullOrEmpty(webBrowser.Document.GetElementById("uiDynamicText").InnerText);
});
var t1 = doc1.DocumentNode.SelectSingleNode("//div[@id='uiDynamicText']").InnerText; var web2 = new HtmlWeb();
var doc2 = web2.LoadFromBrowser(url, html =>
{
// WAIT until the dynamic text is set
return !html.Contains("<div id=\"uiDynamicText\"></div>");
});
var t2 = doc2.DocumentNode.SelectSingleNode("//div[@id='uiDynamicText']").InnerText; Console.WriteLine("Text 1: " + t1);
Console.WriteLine("Text 2: " + t2);

此方法需要在WinForm中使用。通过LoadFromBrowser方法来加载.

2、选择器

(1) SelectNodes(),选择与xPath表达式匹配的节点,如果不存在匹配的节点,则返回null.

示例1:返回匹配表达式“/td/input”的节点集合

var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(html);
string name = htmlDoc.DocumentNode
.SelectNodes("//td/input");

当需要只返回匹配的第一个节点时,用.first。

string name = htmlDoc.DocumentNode
.SelectNodes("//td/input")
.First()

用first的前提是这种节点要存在。否则返回的是null时不能再用first。因此可以先获取匹配的节点集合,判断不为空的情况下,再用first:

var inputNodes = htmlDoc.DocumentNode.SelectNodes("//td/input");
if (inputNodes!=null)
{
  string name = inputNodes.First();
}

示例2:通过class或者id等返回匹配节点,以下是为了获取class='news-item'的所有div节点。

var mainNode = htmlDoc.DocumentNode.SelectNodes(@"//div[@class='news-item']");

当然,div可以根据需要换成span、h1、img等节点。class也可以根据需要换成id或其他。

(2) SelectSingleNode 。获取第一个匹配Xpath表达式的节点。节点不存在则返回null。

示例1:

var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(html); string name = htmlDoc.DocumentNode
.SelectSingleNode("//td/input");

示例2:

var firstNode = htmlDoc.DocumentNode.SelectSingleNode(@"//div[@class='viewport']");

(3)结合linq的使用更强大: 通过where方法或者firstordefault方法,以及节点的特性或者节点的内容等获取节点。

示例:

HtmlWeb web = new HtmlWeb();
var doc = web.Load(model.Url);
var textNode = doc.DocumentNode.Descendants("div").FirstOrDefault(m => m.GetAttributeValue("class", "") == "text" && m.GetAttributeValue("dir", "") == "ltr"); var tdNode = htmlDoc.DocumentNode.SelectNodes(@"//td[@colspan='3']").Where(n => n.InnerHtml.Contains("<a href=") && n.InnerHtml.Contains("<p align=")).FirstOrDefault();
3、通过以上方式获取节点后,就可以对节点进行操作了。

InnerHtml:获取或设置节点内的html。

var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(html); var htmlNodes = htmlDoc.DocumentNode.SelectNodes("//body/h1"); foreach (var node in htmlNodes)
{
Console.WriteLine(node.InnerHtml);
}

InnerText:获取或设置节点内的text。

var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(html); var htmlNodes = htmlDoc.DocumentNode.SelectNodes("//body/h1"); foreach (var node in htmlNodes)
{
Console.WriteLine(node.InnerText);
}

AppendChild:向指定节点的末尾增加子节点:

var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(html); var htmlBody = htmlDoc.DocumentNode.SelectSingleNode("//body"); HtmlNode h2Node = HtmlNode.CreateNode("<h2> This is h2 heading</h2>"); htmlBody.AppendChild(h2Node);

Remove:移除节点

var htmlDoc = new HtmlDocument();

htmlDoc.LoadHtml(html);

var htmlBody = htmlDoc.DocumentNode.SelectSingleNode("//body");

HtmlNode node = htmlBody.ChildNodes[];

node.Remove();
遍历

ChildNodes:获取所有子节点:

var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(html); var htmlBody = htmlDoc.DocumentNode.SelectSingleNode("//body"); HtmlNodeCollection childNodes = htmlBody.ChildNodes; foreach (var node in childNodes)
{
if (node.NodeType == HtmlNodeType.Element)
{
Console.WriteLine(node.OuterHtml);
}
}

FirstChild:获取第一个子节点:

var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(html); var htmlNodes = htmlDoc.DocumentNode.SelectNodes("//body"); var htmlBody = htmlDoc.DocumentNode.SelectSingleNode("//body"); HtmlNode firstChild = htmlBody.FirstChild; Console.WriteLine(firstChild.OuterHtml);

LastChild:获取最后一个子节点,示例同上。

Descendants():返回所有后代节点:

var node = htmlDoc.DocumentNode.SelectSingleNode("//body");

foreach (var nNode in node.Descendants())
{
if (nNode.NodeType == HtmlNodeType.Element)
{
Console.WriteLine(nNode.Name);
}
}

Descendants(String):获取指定名称的后代节点:

var node = htmlDoc.DocumentNode.SelectSingleNode("//body");

foreach (var nNode in node.Descendants("h2"))
{
if (nNode.NodeType == HtmlNodeType.Element)
{
Console.WriteLine(nNode.Name);
}
}
属性

SetAttributeVaule设置节点属性:

var h1Node = htmlDoc.DocumentNode.SelectSingleNode("//h1");

h1Node.Attributes.Append("style");

h1Node.SetAttributeValue("style", "color:blue");

GetAttributeVaule获取节点属性:

如下例子中常用来在爬虫中获取音视频的url

var source = htmlDoc.DocumentNode.SelectSingleNode(@"//source[@type='audio/mpeg']");
var audioUrl = source.GetAttributeValue("src", "");

如下示例常用来在爬虫中获取title

var title = childHtmlDoc.DocumentNode.SelectSingleNode(@"//input[@name='title']").GetAttributeValue("value", "");

强大而灵活的的Html解析器——Html Agility Pack的更多相关文章

  1. [Swift通天遁地]一、超级工具-(18)创建强大、灵活的日期时间拾取器

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  2. Solr Dismax查询解析器-深入分析

    Solr 支持多种查询解析,给搜索引擎开发人员提供灵活的查询解析.Solr 中主要包含这几个查询解析器:标准查询解析器.DisMax 查询解析器,扩展 DisMax 查询解析器(eDisMax) Di ...

  3. DRF之解析器组件及序列化组件

    知识点复习回顾一:三元运算 三元运算能够简化我们的代码,  请看如下代码: # 定义两个变量 a = 1 b = 2 # 判断a的真假值,如果为True,则将判断表达式的前面的值赋给c,否则将判断表达 ...

  4. 邵国际: C 语言对象化设计实例 —— 命令解析器

    本文系转载,著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 作者: 邵国际 来源: 微信公众号linux阅码场(id: linuxdev) 内容简介 单片机工程师常常疑惑为什么 ...

  5. SpringMVC(一)概述、解析器与注解

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.SpringMVC的概述 1.概述 Spring MVC框架是一个开源的Java平台,为开发强大的基 ...

  6. SQL解析器详解

    1.概述 最近,有同学留言关于SQL解析器方面的问题,今天笔者就为大家分享一下SQL解析器方便的一些内容. 2.内容 2.1 SQL解析器是什么? SQL解析与优化是属于编辑器方面的知识,与C语言这类 ...

  7. 如何实现一个SQL解析器

    ​作者:vivo 互联网搜索团队- Deng Jie 一.背景 随着技术的不断的发展,在大数据领域出现了越来越多的技术框架.而为了降低大数据的学习成本和难度,越来越多的大数据技术和应用开始支持SQL进 ...

  8. XML解析器(转)

    常见C/C++ XML解析器有tinyxml.XERCES.squashxml.xmlite.pugxml.libxml等等,这些解析器有些是支持多语言的,有些只是单纯C/C++的.如果你是第一次接触 ...

  9. PHP Simple HTML DOM解析器

    一直以来使用php解析html文档树都是一个难题.Simple HTML DOM parser 帮我们很好地解决了使用 php html 解析 问题.可以通过这个php类来解析html文档,对其中的h ...

随机推荐

  1. Quartus16.1布线优化选择,重编译可能会满足时序

    流程 (1)在默认的优化编译下,时序违例. (2)在assignments中选择setting. (3)根据需求,选择不同的优化方式,目前选择性能优先. (4)可以发现时序满足要求. 以上.

  2. wiki leaks file link url

    wiki leaks file link url XXX发表于2010-08-07 15:54:56 原始来源:http://www.wikileaks.org/wiki/Category:China ...

  3. 自动化测试框架【windows版】:JMeter + Ant + Jenkins

    前提条件:windows安装了jmeter.ant.jenkins 安装方法参考汇总目录中对应的博文 截图看不清的,可以调大浏览器倍数看 jenkins驱动ant执行,ant驱动jmeter执行 an ...

  4. pandas的读写

    import as pd import numpy as np import matplotlib.pyplot as plt #df.to_excel('C:Users/history/Deskto ...

  5. guns初级使用

    1.下载guns gitee地址:https://gitee.com/stylefeng/guns 这里使用的是Guns v5.1 2.配置环境 2.1 导入项目 解压从gitee上下载的guns源码 ...

  6. IIS 常用命令

    Ø  简介 本文主要介绍 IIS 常用的命令,主要包含以下内容: 1.   IIS  重启方法 2.   站点重启方法 3.   应用程序池重启方法 1.   IIS 重启方法 1)   重启 IIS ...

  7. 深入理解line-height与vertical-align——前端布局常用属性

    line-height.font-size.vertical-align是设置行内元素布局的关键属性.这三个属性是相互依赖的关系,改变行间距离.设置垂直对齐等都需要它们的通力合作.下面将主要介绍lin ...

  8. Flask框架搭建一个日程表

    目录 前言 项目介绍 技术栈 Flask Web开发流程 一.搭建环境 1.1: 创建虚拟环境 1.2: 安装依赖包 1.3: 创建依赖包列表文件 1.4: 测试hello word 二.应用程序开发 ...

  9. mint-ui Picker设置指定初始值

    最近做的项目公司需求是信息输入页设置地址跳转下一页后,再返回信息输入页查看信息时,地址要默认显示前面选择的地址,以此记录下,需要小伙伴可以看看 data{return{}}中设置   :slots 在 ...

  10. 组件或者dom的特殊属性

    key:用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes. 常用姿势: 1.结合 v-for,有相同父元素的子元素必须有唯一key. <ul> <li ...