【问题标题】:How to parse out a html-element without a class, id etc如何解析没有类、id 等的 html 元素
【发布时间】:2019-08-12 12:32:21
【问题描述】:

我对 C# 和 HtmlAgilityPack 有疑问。 我想解析出材料的价格,但我不知道如何访问该项目。它是“tr”中的“td 元素”。问题是有 3 个“td 元素”,我无法访问第二个,而只能访问第一个。我希望你能理解我的问题并能帮助我。

这是我要访问的 HTML 代码:

<tr role="row" class="odd" id="itemTable" data-name="clay_r" data-server="1">
    <td>Lehm</td>
    <td>$191</td>
    <td><input class="itemboxes" data-name="clay_r" data-server="1" type="checkbox"></td>
</tr>

<tr role="row" class="odd" id="itemTable" data-name="coal_r" data-server="1">
    <td>Kohle</td>
    <td>$303</td>
    <td><input class="itemboxes" data-name="coal_r" data-server="1" type="checkbox"></td>
</tr>

这是我用 C# 写下的代码,它可以工作,但仅适用于每个第一个 td 元素:

var products = htmlDocument.DocumentNode.Descendants("div")
                .Where(node => node.GetAttributeValue("id", "")
                .Equals("accordion1")).ToList();

var productListItems = products[0].Descendants("tr")
    .Where(node => node.GetAttributeValue("data-name", "")
    .Contains("")).ToList();


foreach (var productListItem in productListItems)
{
    Console.WriteLine(productListItem.GetAttributeValue("data-name", ""));
    Console.WriteLine(productListItem.Descendants("td").FirstOrDefault().InnerText);

    Console.WriteLine();
}

当我启动程序时,它会显示在控制台中:

粘土_r
莱姆

煤_r
科勒

正如我所愿,但应该显示商品的价格而不是“Lehm”或“Kohle”。

【问题讨论】:

    标签: c# visual-studio html-agility-pack


    【解决方案1】:

    FirstOrDefault() 先返回td(表示&lt;td&gt;Lehm&lt;/td&gt;

    使用这个:

    var tds = productListItem.Descendants("td").ToList();
    
    var name = tds[0].InnerText;
    var price = tds[1].InnerText;
    
    Console.WriteLine(name);
    

    IndexOutOfRange异常注意

    【讨论】:

    • Descendants 返回 IEnumerable,您不能使用索引访问器。要么首先使用ToArray/ToList 枚举,要么使用Skip(1)
    • 感谢您的回答。但是,我有一个问题。我知道,我应该知道,但是由于我对 C# 很陌生,所以我仍然无法做到:prntscr.com/orm6zg 我应该在哪里将您的代码加载到我的项目中?
    • 但我还有另一个问题。现在所有变量都正确显示(prntscr.com/ormdxx)。第一行“数据名称”,第二行“名称”,第三行“价格”。现在我想将每个价格分配给一个变量(字符串),稍后我可以访问它......就像:“字符串 LehmPreis = ”。我希望你能帮助我:)
    • @DavidB 命中:Convert.ToInt32(your_string)
    • 是的,但我需要将“价格”转换为字符串。如何使用您的代码执行此操作?我只想为每种材料创建一个字符串(大约 30 个字符串),然后获取这些字符串中每种特定材料的价格。这是因为我需要计算器的这个值,它从服务器获取数字。现在我想获取这些值并计算一个取决于用户选择的材料的值。
    【解决方案2】:

    Antoine V 的替代解决方案,非常干净: 我会用属性“price”命名 tds,并在 where 中添加一个指向“price”的子句。

    并通过这种方式访问​​它:

    替换这个

    Console.WriteLine(productListItem.GetAttributeValue("data-name", ""));
    

    由此

    Console.WriteLine(productListItem.Attributes['price'].value));
    

    否则,为每个td添加一个类(例如“name”“price”和“chkbox”)

    Console.WriteLine(productListItem.Descendants("td").Attributes["price"].value);
    

    希望有帮助吗?

    【讨论】:

    • 查看编辑大卫?刚刚为您添加了另一种选择
    猜你喜欢
    • 2023-01-04
    • 1970-01-01
    • 2010-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-25
    相关资源
    最近更新 更多