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

HtmlAgilityPack数据混乱:如何提取单条广告节点内的信息?

解决广告卡片内信息提取的XPath路径问题

你的推测完全正确://*[@class='...']这种以双斜杠开头的XPath表达式,会从整个HTML文档的根节点开始搜索匹配元素,而不是限定在当前的mainCard[i]节点范围内。这就是为什么每次都返回同一个标题的原因。

修正方案:使用相对路径XPath

要在当前节点的范围内查找子元素,需要使用相对路径:

  • 用.//开头:表示从当前节点开始,搜索所有后代节点(包括子节点、孙节点等)
  • 或者直接写子节点路径(如果目标元素是直接子节点)

修正后的单卡片标题提取代码

var url = url_textbox.Text;
var web = new HtmlWeb();
var doc = web.Load(url);

// 先获取所有广告卡片节点(请根据实际页面结构调整XPath)
var mainCard = doc.DocumentNode.SelectNodes("//div[@id='AdCardId']");
if (mainCard != null)
{
    for (int i = 0; i < mainCard.Count; i++)
    {
        // 使用.//限定在当前卡片节点内查找标题
        var titleNode = mainCard[i].SelectSingleNode(".//*[@class='" + adTitleClassName + "']");
        if (titleNode != null)
        {
            var title = titleNode.InnerText;
            Print(title); // 现在会输出每个卡片对应的标题
        }
    }
}

完整的广告信息提取优化代码

把所有字段的提取都改成相对路径,彻底解决信息错乱问题:

var url = url_textbox.Text;
var web = new HtmlWeb();
var doc = web.Load(url);

// 选中所有广告卡片节点(请根据实际页面结构调整XPath)
var adCards = doc.DocumentNode.SelectNodes("//div[@class='css-1sw7q4x']"); // 示例OLX卡片类名,替换为你的实际选择器
if (adCards != null)
{
    foreach (var card in adCards)
    {
        // 从当前卡片内提取所有信息
        var titleNode = card.SelectSingleNode(".//*[@class='" + adTitleClassName + "']");
        var priceNode = card.SelectSingleNode(".//*[@class='" + adPriceClassName + "']");
        var linkNode = card.SelectSingleNode(".//*[@class='" + adLinkClassName + "']");
        var damagedNode = card.SelectSingleNode(".//*[@class='" + adDamagedClassName + "']");
        var locationNode = card.SelectSingleNode(".//*[@class='" + adLocationClassName + "']");
        var imageContainer = card.SelectSingleNode(".//div[@class='css-gl6djm']");
        var imageNode = imageContainer?.SelectSingleNode(".//img");

        // 空值判断,避免空引用异常
        if (titleNode == null || priceNode == null || linkNode == null) continue;

        var title = titleNode.InnerText.Trim();
        var priceText = priceNode.InnerText.Trim();
        var link = linkNode.GetAttributeValue("href", "");
        var damagedText = damagedNode?.InnerText.Trim() ?? "";
        var timeAdded = locationNode?.InnerText.Trim() ?? "";
        var imageUrl = imageNode?.GetAttributeValue("src", "") ?? "";

        // 解析价格和损坏状态
        var damagedParsed = damagedText == "Uszkodzone";
        var negotiate = priceText.Contains("do negocjacji");
        double.TryParse(priceText.Replace("do negocjacji", "").Replace(" zł", "").Replace(" ", ""), out var price);

        var ad = new Ad
        {
            Title = title,
            Price = price,
            URL = string.IsNullOrEmpty(link) ? "" : "https://www.olx.pl" + link,
            Damaged = damagedParsed,
            TimeAdded = timeAdded,
            ImageURL = imageUrl,
            Negotiate = negotiate
        };

        // 过滤iPhone广告(如果需要)
        if (only_iphone_checkBox.Checked)
        {
            var lowerTitle = title.ToLower();
            if (lowerTitle.Contains("iphone") || lowerTitle.Contains("apple"))
            {
                ads.Add(ad);
            }
        }
        else
        {
            ads.Add(ad);
        }
    }
}

// 渲染广告列表
foreach (Ad ad in ads)
{
    AdItem adItem = new AdItem(ad);
    ads_list.Controls.Add(adItem);
}

关键注意点

  1. XPath路径规则:
    • //xxx:绝对路径,从文档根开始搜索
    • .//xxx:相对路径,从当前节点开始搜索后代
    • ./xxx:仅搜索当前节点的直接子元素
  2. 空值判断:添加节点空值检查,避免页面结构变化导致的异常
  3. 卡片选择器准确性:确保adCards的XPath能正确选中每个独立广告卡片,这是后续提取的基础

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 18:35:05