C# 使用HtmlAgilityPack解析提取HTML内容

写在前面

HtmlAgilityPack是一个HTML解析类库,日常用法就是爬虫获取到内容后,先用XPath获取目标节点,再用正则进行匹配;使用XPath的目的主要是将目标节点或内容限定在一个较小的范围,如果一上来就用正则那效率肯定不行,因为正则的规则设计耗时较长;而XPath直接可以用浏览器F12开发者工具窗口,鼠标右键复制XPath获得,非常方便。但在微观内容的操作上XPath就显得太粗糙了,这时候就需要用正则来匹配,由于范围已经用XPath做过了筛选,所以此时的正则规则的设计要考虑的就很少了;两者结合效率就大大提升了,解析HTML源码实在是个耗时费力的体力活。

老套路通过NuGet获取类库

代码实现

cs 复制代码
    using HtmlAgilityPack;

    public static class HtmlDocumentMgr
    {
        #region Public Methods

        public static HtmlNodeCollection GetNodes(string xPath)
        {
            var body = BrowserController.GetFrameBody();
            var doc = GetHtmlDocument(body);
            return doc.DocumentNode.SelectNodes(xPath);
        }

        public static HtmlNode GetNode(string xPath)
        {
            var body = BrowserController.GetFrameBody();
            var doc = GetHtmlDocument(body);
            return doc.DocumentNode.SelectSingleNode(xPath);
        }

        public static HtmlDocument GetHtmlDocument(string html)
        {
            var doc = new HtmlDocument();
            doc.LoadHtml(html);
            return doc;
        }


        #endregion

    }

HTML 内容可以是独立爬虫直接获取的,也可以从内嵌浏览器中获得,本文采用内嵌浏览器的方式,获得HTML的代码如下,仅做参考示意。

cs 复制代码
        public static string GetFrameBody()
        {
            var js = "document.querySelector('body').outerHTML";
            var evalRet = Browser.MainFrame.EvaluateScriptAsync(js);
            evalRet.Wait();
            if (evalRet.Result != null)
            {
                var ret = evalRet.Result.Result;
                return ret.ToNormalString();
            }
            return string.Empty;
        }

调用示例

cs 复制代码
        public static HtmlNode GetDescribeNode(string describe)
        {
            var body = BrowserController.GetFrameBody();
            var doc = new HtmlDocument();
            doc.LoadHtml(body);

            var match = string.Format(".//label[contains(text(), \"{0}\")]", describe);
            var labelNode = doc.DocumentNode.SelectSingleNode(match);
            if (labelNode == null && describe.Contains(" "))
            {
                describe = describe.Replace(" ", " ");
                match = string.Format(".//label[contains(text(), \"{0}\")]", describe);
                labelNode = doc.DocumentNode.SelectSingleNode(match);
            }
            return labelNode;
        }
相关推荐
Lyyaoo.2 小时前
【JAVA基础面经】JVM的内存模型
java·开发语言·jvm
杨凯凡2 小时前
【017】泛型与通配符:API 设计里怎么用省心
java·开发语言
2401_873479408 小时前
如何利用IP查询定位识别电商刷单?4个关键指标+工具配置方案
开发语言·tcp/ip·php
我爱cope9 小时前
【从0开始学设计模式-10| 装饰模式】
java·开发语言·设计模式
rockey6279 小时前
AScript函数体系详解
c#·.net·script·eval·expression·function·动态脚本
菜鸟学Python9 小时前
Python生态在悄悄改变:FastAPI全面反超,Django和Flask还行吗?
开发语言·python·django·flask·fastapi
浪浪小洋10 小时前
c++ qt课设定制
开发语言·c++
charlie11451419110 小时前
嵌入式C++工程实践第16篇:第四次重构 —— LED模板,从通用GPIO到专用抽象
c语言·开发语言·c++·驱动开发·嵌入式硬件·重构
故事和你9110 小时前
洛谷-数据结构1-4-图的基本应用1
开发语言·数据结构·算法·深度优先·动态规划·图论
程序猿编码11 小时前
给你的网络流量穿件“隐形衣“:手把手教你用对称加密打造透明安全隧道
linux·开发语言·网络·安全·linux内核