HtmlAgilityPack 操作详解
目录
1.安装 HtmlAgilityPack
2. 示例 HTML
3. 使用 HtmlAgilityPack 进行 HTML 解析与操作
4. 代码详解
1.加载html文档
2.选择元素
3. 提取属性
4.修改属性
5.常用的几种获取元素的 XPath 写法
HtmlAgilityPack:
- 轻量且高效,适合进行常规的 HTML 解析。
- 由于其轻量化设计,在只需简单提取或修改元素内容时,HtmlAgilityPack 会显得更快。
- 对于层级较深或大规模的 HTML 文档,HtmlAgilityPack 也会处理得较为流畅。
- 文件大小较小,功能单一,适用于解析 HTML 和使用 XPath 查询。
- 没有内置对 CSS 选择器的支持,需要通过额外库扩展(如 Fizzler)。
1.安装 HtmlAgilityPack
通过 NuGet 包管理器安装 HtmlAgilityPack:

2. 示例 HTML
假设我们有以下 HTML 内容,需要解析和操作:
<!DOCTYPE html><html><head><title>HtmlAgilityPack Example</title><style>.highlight { color: yellow; }#main { background-color: #f0f0f0; }</style></head><body><h1 id='main-heading' class='highlight'>Welcome to HtmlAgilityPack</h1><p>This is a <span class='highlight'>simple</span> example.</p><a href='https://example.com' target='_blank'>Visit Example.com</a><ul id='items'><li class='item'>Item 1</li><li class='item'>Item 2</li><li class='item'>Item 3</li></ul><input type='text' id='username' value='JohnDoe' /><input type='password' id='password' /></body></html>
3. 使用 HtmlAgilityPack 进行 HTML 解析与操作
以下是一个详细的 C# 示例,展示如何使用 HtmlAgilityPack 进行各种操作:
using HtmlAgilityPack;
using System;
using System.Linq;class Program
{static void Main(string[] args){// 示例 HTML 内容string html = @"<!DOCTYPE html><html><head><title>HtmlAgilityPack Example</title><style>.highlight { color: yellow; }#main { background-color: #f0f0f0; }</style></head><body><h1 id='main-heading' class='highlight'>Welcome to HtmlAgilityPack</h1><p>This is a <span class='highlight'>simple</span> example.</p><a href='https://example.com' target='_blank'>Visit Example.com</a><ul id='items'><li class='item'>Item 1</li><li class='item'>Item 2</li><li class='item'>Item 3</li></ul><input type='text' id='username' value='JohnDoe' /><input type='password' id='password' /></body></html>";// 1. **加载 HTML 文档**HtmlDocument document = new HtmlDocument();document.LoadHtml(html);// 2. **选择元素**// 使用 XPath 选择所有具有 class 'highlight' 的元素var highlights = document.DocumentNode.SelectNodes("//*[@class='highlight']");Console.WriteLine("Elements with class 'highlight':");foreach (var elem in highlights){Console.WriteLine($"- <{elem.Name}>: {elem.InnerText}");}// 使用 ID 选择器选择特定元素var mainHeading = document.GetElementbyId("main-heading");if (mainHeading != null){Console.WriteLine($"\nElement with ID 'main-heading': {mainHeading.InnerText}");}// 选择所有 <a> 标签var links = document.DocumentNode.SelectNodes("//a");Console.WriteLine("\nAll <a> elements:");foreach (var link in links){Console.WriteLine($"- Text: {link.InnerText}, Href: {link.GetAttributeValue("href", "")}, Target: {link.GetAttributeValue("target", "")}");}// 选择所有具有 class 'item' 的 <li> 元素var items = document.DocumentNode.SelectNodes("//li[@class='item']");Console.WriteLine("\nList items with class 'item':");foreach (var item in items){Console.WriteLine($"- {item.InnerText}");}// 选择特定类型的输入元素var textInput = document.DocumentNode.SelectSingleNode("//input[@type='text']");var passwordInput = document.DocumentNode.SelectSingleNode("//input[@type='password']");Console.WriteLine($"\nText Input Value: {textInput.GetAttributeValue("value", "")}");Console.WriteLine($"Password Input Value: {passwordInput.GetAttributeValue("value", "")}");// 3. **提取和修改属性**// 获取第一个链接的 href 属性string firstLinkHref = links.First().GetAttributeValue("href", "");Console.WriteLine($"\nFirst link href: {firstLinkHref}");// 修改第一个链接的 href 属性links.First().SetAttributeValue("href", "https://newexample.com");Console.WriteLine($"Modified first link href: {links.First().GetAttributeValue("href", "")}");// 4. **提取和修改文本内容**// 获取第一个段落的文本内容var firstParagraph = document.DocumentNode.SelectSingleNode("//p");Console.WriteLine($"\nFirst paragraph text: {firstParagraph.InnerText}");// 修改第一个段落的文本内容firstParagraph.InnerHtml = "This is an <strong>updated</strong> example.";Console.WriteLine($"Modified first paragraph HTML: {firstParagraph.InnerHtml}");// 5. **操作样式**// 获取元素的 class 属性string h1Classes = mainHeading.GetAttributeValue("class", "");Console.WriteLine($"\nMain heading classes: {h1Classes}");// 添加一个新的 classmainHeading.SetAttributeValue("class", h1Classes + " new-class");Console.WriteLine($"Main heading classes after adding 'new-class': {mainHeading.GetAttributeValue("class", "")}");// 移除一个 class (手动实现,HtmlAgilityPack 不支持内置的 class 操作)h1Classes = mainHeading.GetAttributeValue("class", "").Replace("highlight", "").Trim();mainHeading.SetAttributeValue("class", h1Classes);Console.WriteLine($"Main heading classes after removing 'highlight': {mainHeading.GetAttributeValue("class", "")}");// 6. **遍历和查询 DOM**// 遍历所有子节点的标签名Console.WriteLine("\nChild elements of <body>:");var bodyChildren = document.DocumentNode.SelectSingleNode("//body").ChildNodes;foreach (var child in bodyChildren){if (child.NodeType == HtmlNodeType.Element){Console.WriteLine($"- <{child.Name}>");}}// 查找包含特定文本的元素var elementsWithText = document.DocumentNode.SelectNodes("//*[contains(text(), 'simple')]");Console.WriteLine("\nElements containing the text 'simple':");foreach (var elem in elementsWithText){Console.WriteLine($"- <{elem.Name}>: {elem.InnerText}");}// 7. **生成和输出修改后的 HTML**string modifiedHtml = document.DocumentNode.OuterHtml;Console.WriteLine("\nModified HTML:");Console.WriteLine(modifiedHtml);}
}
4. 代码详解
1.加载html文档
HtmlDocument document = new HtmlDocument();
document.LoadHtml(html);
2.选择元素
- 使用 XPath 选择所有具有相同特征的元素集合 .SelectNodes("XPath");
var elements = document.DocumentNode.SelectNodes("//*[@class='class']"); - 通过 XPath 选择具有独立性的单一元素 .SelectSingleNode("XPath");
var div = document.DocumentNode.SelectSingleNode("//div[@id='title-content']"); - 使用 ID 选择器选择特定元素 .GetElementbyId("id");
var element = document.GetElementbyId("id"); -
获取子节点(注意这里是直接子节点集合,即第一级的子节点。不包括更深层次的子孙节点。).ChildNodes;
var bodyChildren = document.DocumentNode.SelectSingleNode("//body").ChildNodes; - 获取元素的第一个子节点 .First();
var firstChildNode = element.First();
3. 提取属性
假设我们要对下面这个 element 进行操作
var element = document.GetElementbyId("id");
- 提取元素内部 html
string innerHtml = element.InnerHtml; - 提取含元素自身的 html
string outerHtml = element.OuterHtml; - 提取文本
string text= element.InnerText; - 提取属性
string _value = element.GetAttributeValue("value", ""); - 提取 href
string href = element.GetAttributeValue("href", "");
4.修改属性
-
修改 href
element.SetAttributeValue("href", "https://newexample.com"); - 添加 class
element.SetAttributeValue("class", oldClasses + " new-class"); - 修改 class
// 移除一个 class (手动实现,HtmlAgilityPack 不支持内置的 class 操作) newClasses = element.GetAttributeValue("class", "").Replace("highlight", "").Trim(); element.SetAttributeValue("class", newClasses);
5.常用的几种获取元素的 XPath 写法
- 通过 id 获取
var element = document.DocumentNode.SelectSingleNode("//*[@id='id']"); - 通过 class 获取
var element = document.DocumentNode.SelectNodes("//*[@class='class']"); - 通过匹配文本获取
var elementsWithText = document.DocumentNode.SelectNodes("//*[contains(text(), 'simple')]"); - 通过 class 和 匹配文本 相结合获取
var elements = doc.DocumentNode.SelectNodes("//span[@class='title-content-title' and contains(text(), '包含的文本')]");
相关文章:
HtmlAgilityPack 操作详解
目录 1.安装 HtmlAgilityPack 2. 示例 HTML 3. 使用 HtmlAgilityPack 进行 HTML 解析与操作 4. 代码详解 1.加载html文档 2.选择元素 3. 提取属性 4.修改属性 5.常用的几种获取元素的 XPath 写法 HtmlAgilityPack: 轻量且高效,适合进行常规的 H…...
基于SSM医院门诊互联电子病历管理系统的设计
管理员账户功能包括:系统首页,个人中心,用户管理,医生管理,项目分类管理,项目信息管理,预约信息管理,检查信息管理,系统管理 用户账号功能包括:系统首页&…...
【读书笔记/深入理解K8S】集群网络
前言 上一章讲了集群控制器的一个大概的原理,这一章讲一下集群网络。网络是集群通信的载体,因为该书是阿里云团队出品的,所以也以阿里云的集群网络方案为例,其他云厂商的网络集群方案一般来说也大同小异。所以通过本章的学习&…...
【专有网络VPC】连接公网
通过ECS实例固定公网IP、弹性公网IP、NAT网关、负载均衡使专有网络中的云资源可以访问公网(Internet)或被公网访问。 概述 专有网络是您自定义的云上私有网络。专有网络中的云资源默认无法访问公网,也无法被公网访问。您可以通过配置ECS实例…...
论文 | Legal Prompt Engineering for Multilingual Legal Judgement Prediction
这篇文章探讨了如何利用“法律提示工程”(LPE)来指导大型语言模型(LLM)进行多语言法律判决预测(LJP)。主要内容: LPE 的概念: LPE 是指通过设计特定的提示(promp…...
国科安芯抗辐照MCU和CANFD芯片发布
国科安芯科技有限公司近期发布了两款重要的芯片产品:抗辐照MCU芯片和抗辐照CANFD芯片。这两款芯片的发布标志着国科安芯在高性能、高安全性芯片产品研制方面取得了显著进展,特别是在抗辐照技术领域。 1. 抗辐照MCU芯片:国科安芯研发的AS32A4…...
C++ 并发专题 - 无锁数据结构(概述)
一:概述: 无锁数据结构是一种在多线程环境中实现线程安全的结构,它允许多个线程在没有传统锁机制的情况下并发访问和修改数据。这种设计的目标是提高程序的性能和响应性,避免锁竞争和上下文切换的开销。 二:原理&…...
NLP领域的经典算法和模型
在自然语言处理(NLP)领域,经典算法和模型众多,它们在不同任务中发挥着重要作用。以下是一些NLP领域的经典算法和模型的详细介绍: 一、基础模型 词袋模型(Bag of Words,BoW) 原理&a…...
提升安全上网体验:Windows 11 启用 DOH(阿里公共DNS)
文章目录 阿里公共 DNS 介绍免费开通云解析 DNS 服务Windows 编辑 DNS 设置配置 IPv4配置 IPv6 路由器配置 DNS 阿里公共 DNS 介绍 https://alidns.com/ 免费开通云解析 DNS 服务 https://dnsnext.console.aliyun.com/pubDNS 开通服务后,获取 DOH 模板࿰…...
论文概览 |《Journal of Transport Geography》2024.10 Vol.120
本次给大家整理的是《Journal of Transport Geography》杂志2024年9月第120卷的论文的题目和摘要,一共包括17篇SCI论文! 论文1 Modelling scenarios in planning for future employment growth in Stockholm 斯德哥尔摩未来就业增长规划情景建模 【摘要…...
yum不能使用: cannot find a valid baseurl for repo: base/7/x86_64
使用yum命令时报错: 原因: CentOS 已经停止维护的问题。2020 年 12 月 8 号,CentOS 官方宣布了停止维护 CentOS Linux 的计划,并推出了 CentOS Stream 项目,CentOS Linux 8 作为 RHEL 8 的复刻版本,生命周期…...
什么品牌的护眼台灯比较好?五款护眼效果比较明显的护眼台灯
在当今信息爆炸的时代背景下,挑选一款真正符合个人需求的护眼台灯,确实是一项不小的挑战。市场上品牌众多、型号繁杂,功能特点各不相同,价格区间也相当广泛,许多消费者在选购时往往感到迷茫不已。当大家询问“什么品牌…...
HTML 表单设计与验证
创建 HTML 表单的步骤如下: 使用 <form> 标签来创建表单,<form> 标签有一个 action 属性,用于指定表单提交的目标 URL。 在 <form> 标签内部,使用 <input> 标签来创建输入框。<input> 标签有一个 …...
qt QDialog详解
1、概述 QDialog是Qt框架中用于创建对话框的类,它继承自QWidget。QDialog提供了一个模态或非模态的对话框,用于与用户进行交互。模态对话框会阻塞其他窗口的输入,直到用户关闭该对话框;而非模态对话框则允许用户同时与多个窗口进…...
supervisor服务“Exited too quickly“解决方案
【初始问题】supervisor创建一个守护进程,老是提示启动失败 【结论】进程执行后,短时间就断开了 Ⅰ 问题分析 supervisor开启进程守护失败了,查看下进程执行记录,显示这个进程的指令执行报错了 接下来,查看下superv…...
动态规划 —— 路径问题-地下城游戏
1. 地下城游戏 题目链接: 174. 地下城游戏 - 力扣(LeetCode)https://leetcode.cn/problems/dungeon-game/description/ 2. 算法原理 状态表示:以莫一个位置位置为结尾或者以莫一个位置为起点 dp[i,j]表示:…...
沈阳乐晟睿浩科技有限公司抖音小店短视频时代的电商蓝海
在数字化浪潮席卷全球的今天,电子商务以其独特的魅力和无限的潜力,成为了推动经济发展的新引擎。作为这一领域的佼佼者,沈阳乐晟睿浩科技有限公司凭借其深厚的行业积淀与创新精神,正逐步成为众多商家在抖音小店平台上腾飞的强大助…...
ubuntu20.04安装ros与rosdep
目录 前置配置 配置apt清华源 配置ros软件源 添加ros安装源(中科大软件源) 设置秘钥 更新源 ros安装 安装ros 初始化 rosdep 更新 rosdep 设置环境变量 安装 rosinstall 安装验证 启动海龟仿真器 操控海龟仿真器 rosdep安装更新 安装 使用…...
推理加速papers
《A Survey on Efficient Inference for Large Language Models》2024-07 1. Q、K、V的计算,都是矩阵乘法; 2. prefilling阶段,每次计算,Q是N个向量一起;decoding阶段,每次计算,Q是1个向量计算&…...
【02基础】- RabbitMQ基础
目录 2- RabbitMQ2-1 介绍和安装安装 2-2 RabbitMQ 快速入门2-3 RabbitMQ 数据隔离 3- Java客户端3-1 快速入门AMQP快速入门📑小结:SpringAMQP如何收发消息? 3-2 WorkQueues 任务模型案例-使用 WorkQueue 单队列绑定多消费者📑小结…...
从零开始在Taotoken模型广场选择并测试最适合的模型
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 从零开始在Taotoken模型广场选择并测试最适合的模型 当你开始使用大模型时,面对众多厂商和不同能力的模型,…...
无王无帝定乾坤,来自田间第一人 立凰标定世序
谶曰 乱世去旧制,盛世出布衣。 凰标立天地,大同自此始。 一、破题:王权之外,另有乾坤 世人皆道 “普天之下,莫非王土;率土之滨,莫非王臣。” 却不知真正的变局, 起于垄亩࿰…...
STM32F407移植EasyFlash:嵌入式Flash键值存储与磨损均衡实战
1. 项目概述:为什么要在STM32F407上折腾EasyFlash?最近在做一个基于STM32F407的物联网终端设备,功能上需要记录一些运行参数、用户配置,还得在意外断电后能恢复现场。最开始想着用片内Flash模拟EEPROM,自己写读写擦除逻…...
2025最权威的十大AI科研工具推荐
Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 学术研讨范畴正在历经深度的变动,人工智能论文工具现身,极大地提高了…...
3步完成Android Studio中文界面配置:终极汉化指南
3步完成Android Studio中文界面配置:终极汉化指南 【免费下载链接】AndroidStudioChineseLanguagePack AndroidStudio中文插件(官方修改版本) 项目地址: https://gitcode.com/gh_mirrors/an/AndroidStudioChineseLanguagePack 还在为Android Stud…...
华为防火墙双出口场景下基于IP-Link的GRE over IPSec高可用方案实战
1. 华为防火墙双出口高可用方案实战指南 企业网络多出口环境下的VPN高可用性一直是网络工程师的痛点。去年我负责某连锁企业总部与30家分支的VPN改造项目,就遇到过主链路中断导致收银系统瘫痪的尴尬情况。今天要分享的这套基于IP-Link的GRE over IPSec方案ÿ…...
给项目选YOLO模型别再纠结了:从参数量、训练曲线到mAP,手把手教你根据数据集做决策
YOLO模型选型实战指南:从参数解析到场景适配的决策方法论 在目标检测领域,YOLO系列模型凭借其出色的实时性能,已成为工业界和学术界的首选架构之一。然而,面对从YOLOv5到YOLOv9的多个版本迭代,以及每个版本中不同规模的…...
DIY红外遥控电视关机器:从ATTINY85到晶体管驱动的硬件实践
1. 项目概述:从“关不掉”的烦恼到“一键清静”的实践不知道你有没有过这样的经历:在餐厅吃饭,墙上挂着的电视正播放着吵闹的广告;在候车室,多台电视同时播放着不同的节目,让人心烦意乱。你只想安安静静地待…...
【USB3.0协议探秘】实战篇·三种复位事件的触发机制与链路状态变迁
1. 认识USB3.0的三种复位机制 刚接触USB3.0协议时,很多人会被各种复位类型绕晕。在实际开发中,我就遇到过因为混淆PowerOn Reset和Warm Reset导致设备无法正常初始化的情况。今天我们就来彻底搞懂这三种复位机制的区别和应用场景。 USB3.0协议定义了三种…...
【智能算法】淘金优化算法(GRO)实战:从理论到代码的寻优之旅
1. 淘金优化算法(GRO)初探:从挖矿到代码的奇妙映射 第一次听说淘金优化算法时,我脑海中立刻浮现出19世纪美国西部的淘金热场景。有趣的是,这个算法的发明者K Zolf团队正是从这段历史中获得灵感。想象一下,…...
