htmlagilitypack 是 c# 中处理 html 最稳妥的库,尤其适合容错爬虫;documentnode 为 null 是常见异常根源,需先校验;selectnodes() 仅支持 xpath 1.0,不兼容 css 选择器;提取文本需预清理 script/style/注释并正则规范化空白。

HtmlAgilityPack 是当前 C# 中处理 HTML 源码最稳妥的选择,尤其适合爬虫场景下的容错解析。它不依赖浏览器引擎,不执行 JS,但对 malformed HTML(比如缺失闭合标签、嵌套错乱)容忍度高——这点比 AngleSharp 或 WebBrowser 更适合批量抓取不可控的网页。
HtmlDocument.LoadHtml() 报 NullReferenceException 怎么办
根本原因不是代码写错了,而是 DocumentNode 为 null,后续任何 SelectNodes() 或 GetAttributeValue() 都会崩。
-
LoadHtml()输入为空字符串、纯文本、或只有片段(如"<div>xxx</div>")时,DocumentNode可能为null - 网络请求返回空响应(HTTP 204、超时截断、gzip 解压失败)也会导致解析中断
- 编码不匹配(如服务器声明 UTF-8,实际是 GBK)会让解析器在第一个非法字节处静默失败
实操建议:
- 永远先检查:
if (doc.DocumentNode == null) throw new InvalidOperationException("HTML parse failed: DocumentNode is null"); - 解析片段前加一层包裹:
doc.LoadHtml($"<div>{htmlFragment}</div>"); - 从 HTTP 获取后,显式指定编码再传入:
doc.LoadHtml(Encoding.UTF8.GetString(bytes));,别用Load()直接读流
SelectNodes() 查不到元素,但浏览器里明明有
这不是库坏了,是 XPath 和 CSS 选择器的根本差异被忽略了。
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
-
SelectNodes()只接受 XPath 1.0 表达式,不支持div.content、article > h2:first-child这类 CSS 写法 - class 属性含空格(如
class="a b c")时,@class='a b c'会失败——因为 HTML 解析后属性值可能被规范化(空格合并、顺序变动) - 单引号未转义会导致 XPath 解析失败,例如:
"//a[@href='@#@#@#@#@#@#@#@#@#@0']"中的&会被 XML 解析器提前截断
实操建议:
- 把
div.content改成//div[contains(@class, 'content')](注意误匹配风险) - 要精准匹配多 class,用
//div[normalize-space(@class) = 'a b'],前提是原始 HTML 中 class 值完全一致 - 属性值含单引号时,统一改用双引号包裹整个 XPath:
"//a[@href=\"@#@#@#@#@#@#@#@#@#@0\"]" - 不确定路径是否有效?先用
doc.DocumentNode.SelectSingleNode("//*")看能否拿到根节点,再逐级试探
提取文本时出现换行、\u00A0、多余空格
InnerText 是“渲染视角”的粗略模拟,它会保留
<br>换行逻辑、合并空白但不清理 Unicode 空格,还会把
<script></script> 和 <style></style> 里的内容一并拉进来。实操建议:
- 先移除干扰节点:
foreach (var node in doc.DocumentNode.SelectNodes("//script | //style | //comment()")) node.Remove(); - 再用正则清洗:
Regex.Replace(node.InnerText, @"[\s\u00A0\u2000-\u200F\u2028\u2029]+", " ").Trim() - 如果只要纯字母数字,慎用
Where(char.IsLetterOrDigit)——它会干掉中文、货币符号、连字符等业务关键字符
HtmlAgilityPack 的真正难点不在语法,而在 HTML 本身的混沌:服务端动态插入的注释、JS 注入的 DOM、CDN 返回的压缩/分块响应、甚至反爬中间件注入的混淆节点。这些不会报错,但会让 XPath 表达式在第 1000 次请求时突然失效。上线前务必用真实采集样本做回归验证,而不是只测一个“完美 HTML”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










