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

HTMLAgilityPack无法识别首个元素:NBA赛程爬取异常问题

解决ESPN NBA赛程爬取的异常问题

问题根源

ESPN的NBA赛程页面依赖JavaScript动态渲染内容,HtmlWeb直接加载的是服务器返回的原始HTML,并非浏览器渲染后的完整DOM结构。这就导致你获取到的内容缺失了动态生成的当日赛程,反而拿到了预加载的次日内容,同时日期与表格不匹配。

解决方案1:使用无头浏览器获取渲染后页面

推荐用.NET生态下的PuppeteerSharp(无头浏览器库),它能模拟浏览器执行JS,获取完整的渲染后HTML。

  1. 先安装NuGet包:
Install-Package PuppeteerSharp
  1. 示例代码:
using PuppeteerSharp;
using HtmlAgilityPack;

// 下载浏览器(首次运行需要)
var browserFetcher = new BrowserFetcher();
await browserFetcher.DownloadAsync();

// 启动无头浏览器
using var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true });
using var page = await browser.NewPageAsync();

// 等待页面完全加载(直到网络空闲)
await page.GoToAsync("https://www.espn.com/nba/schedule", new NavigationOptions { WaitUntil = WaitUntilNavigation.Networkidle2 });

// 获取渲染后的完整HTML
var renderedHtml = await page.GetContentAsync();

// 用HtmlAgilityPack解析
var doc = new HtmlDocument();
doc.LoadHtml(renderedHtml);

// 遍历每个赛程容器
var scheduleContainers = doc.DocumentNode.SelectNodes("//div[contains(@class, 'ScheduleTables')]");
if (scheduleContainers != null)
{
    foreach (var container in scheduleContainers)
    {
        // 提取日期
        var dateElement = container.SelectSingleNode("./div[not(contains(@class, 'Table'))]");
        var date = dateElement?.InnerText.Trim() ?? "未识别日期";
        
        // 提取对应表格tbody
        var tableBody = container.SelectSingleNode("./table[contains(@class, 'Table')]/tbody");
        if (tableBody != null)
        {
            // 处理表格行数据
            var rows = tableBody.SelectNodes("./tr");
            if (rows != null)
            {
                foreach (var row in rows)
                {
                    // 示例:提取对阵球队和时间
                    var teamNodes = row.SelectNodes("./td[contains(@class, 'team')]");
                    var timeNode = row.SelectSingleNode("./td[contains(@class, 'time')]");
                    
                    if (teamNodes != null && teamNodes.Count == 2 && timeNode != null)
                    {
                        var homeTeam = teamNodes[0].InnerText.Trim();
                        var awayTeam = teamNodes[1].InnerText.Trim();
                        var gameTime = timeNode.InnerText.Trim();
                        // 后续业务逻辑处理...
                    }
                }
            }
        }
    }
}

解决方案2:直接请求API接口(更稳定)

分析浏览器的网络请求,找到ESPN返回赛程数据的API端点,直接请求JSON格式的数据,比解析HTML更可靠:

  1. 打开浏览器开发者工具(F12),切换到「网络」标签;
  2. 刷新赛程页面,筛选XHR/Fetch请求,找到返回赛程数据的接口(通常包含schedule或calendar关键字);
  3. 用HttpClient直接请求该接口,解析返回的JSON数据即可。

注意事项

  • 避免频繁请求,ESPN有反爬机制,可设置请求间隔或添加User-Agent等请求头模拟浏览器;
  • API接口可能会随网站更新变化,需要定期验证。

内容的提问来源于stack exchange,提问作者Łukasz Michalski

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 05:59:53