You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用C#的HtmlAgilityPack爬取网页遇阻:无法获取目标标题

使用HtmlAgilityPack爬取网页标题未得到预期结果的解决方案

嘿,我太懂你被这个问题卡两天的感受了——新手用HtmlAgilityPack爬取动态页面的时候,最容易踩这种坑!咱们一步步来拆解问题,找到解决办法。

先排查核心问题:动态内容 vs 选择器错误

从你用的ng-href属性来看,这个页面大概率是Angular框架渲染的动态页面,而HtmlAgilityPack的HtmlWeb.Load()只能抓取服务器返回的静态HTML,根本执行不了JavaScript,那些通过Angular动态生成的内容自然就抓不到。这是最常见的原因,先重点排查这个。

如果确认是静态页面,那就是你的XPath选择器没命中正确元素,后面也会给你修正方案。


方案一:处理动态内容(大概率是你的问题)

要抓取JS渲染的内容,你需要用能模拟浏览器执行JS的工具,比如Selenium WebDriver或者PuppeteerSharp。这里给你一个Selenium的示例,上手最快:

using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using HtmlAgilityPack;

static string url = "https://xyzabc.com";
static void Main(string[] args)
{
    GetJobeeDataWithSelenium();
    Console.Read();
}

static void GetJobeeDataWithSelenium()
{
    // 初始化Chrome驱动(需要下载和你Chrome版本匹配的chromedriver.exe,放到项目目录)
    var options = new ChromeOptions();
    options.AddArgument("--headless"); // 无头模式,不会弹出浏览器窗口
    using (var driver = new ChromeDriver(options))
    {
        driver.Navigate().GoToUrl(url);
        // 等待页面加载完成(实际项目建议用WebDriverWait等待特定元素,比固定等待更可靠)
        System.Threading.Thread.Sleep(3000); 

        // 获取浏览器渲染后的完整HTML
        string pageSource = driver.PageSource;
        HtmlDocument doc = new HtmlDocument();
        doc.LoadHtml(pageSource);

        // 再用你的选择器尝试抓取
        var titles = doc.DocumentNode.SelectNodes("//a[@ng-href]//p");
        if (titles == null)
        {
            Console.WriteLine("未找到目标标题元素");
        }
        else
        {
            foreach (var item in titles)
            {
                Console.WriteLine($"Jobee Jobs Data: {item.InnerText.Trim()}\n");
            }
        }
    }
}

方案二:修正XPath选择器(如果是静态页面)

如果页面确实是纯静态的,那可能你的选择器不够精准:

  • 试试直接定位a标签的直接子p元素://a[@ng-href]/p(如果p是a的直接子节点,而不是后代节点)
  • 或者加上元素的class/id来缩小范围,比如://a[@ng-href]//p[@class='job-title'](把job-title换成你在浏览器里看到的真实class)
  • 也可以用LINQ方式遍历,更灵活直观:
static void GetJobeeDataWithFixedSelector()
{
    HtmlWeb html = new HtmlWeb();
    HtmlDocument doc = html.Load(url);

    // 先找到所有带ng-href的a标签
    var jobLinks = doc.DocumentNode.Descendants("a")
                     .Where(a => !string.IsNullOrEmpty(a.GetAttributeValue("ng-href", "")));

    foreach (var link in jobLinks)
    {
        // 找当前a标签下的第一个p元素
        var titleTag = link.Descendants("p").FirstOrDefault();
        if (titleTag != null)
        {
            Console.WriteLine($"Jobee Jobs Data: {titleTag.InnerText.Trim()}\n");
        }
    }
}

调试小技巧

  1. 先把doc.DocumentNode.OuterHtml输出到一个本地HTML文件,看看HtmlAgilityPack实际拿到的页面结构是什么样的——如果和你浏览器F12看到的不一样,那肯定是动态内容的问题。
  2. 在浏览器开发者工具里,右键目标元素选择「复制XPath」,直接用这个复制出来的XPath,比自己写的更准确。

内容的提问来源于stack exchange,提问作者Mashood Siddiquie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:00:51