C# HTML Agility Pack获取类名元素

33

我想获取所有 class 中包含特定单词的 div:

<div class="hello mike">content1</div>
<div class="hello jeff>content2</div>
<div class="john">content3</div>

我需要获取所有class中包含单词"hello"的div元素。 类似这样:
resultContent.DocumentNode.SelectNodes("//div[@class='hello']"))

我该如何使用Agility Pack进行操作?

5个回答

44

我明白了:

resultContent.DocumentNode.SelectNodes("//div[contains(@class, 'hello')]")

24

从Html Agility Pack版本v1.6.5开始,它包含.HasClass("class-name")扩展方法。

IEnumerable<HtmlNode> nodes =
    htmlDoc.DocumentNode.Descendants(0)
        .Where(n => n.HasClass("class-name"));

4
以上速度比最流行的答案快5倍——尽管我使用了document.DocumentNode.Descendants().Where(x => x.HasClass(...的方法。 - Jaycee

12

我相信是因为你的 div 中有多个类,所以那样不起作用。你可以尝试使用这个替代方案:

resultContent.DocumentNode.Descendants("div").Where(d => d.Attributes["class"].Value.Contains("hello"));

6
与另一个答案相比,这种方法有一个缺点:如果没有class属性的div元素,它会抛出异常。使用这个方法代替:.Where(d => d.GetAttributeValue("class", "").Contains("hello")); - Tim Schmelter

1

由于您指定了类必须包含某个单词,以下内容将确保该单词为:

  • 在字符串开头并后跟空格
  • 或在字符串中间并被空格包围
  • 或在字符串结尾并前面有空格
  • 或者是类属性中唯一的类名

它通过将由空格包围的类属性值与由空格包围的指定单词 (hello) 进行比较来实现。这是为了避免误报,例如 class="something-hello-something"

resultContent.DocumentNode.SelectNodes("//div[contains(concat(' ', @class, ' '), ' hello ')]");

0
HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
htmlDoc.Load(filePath);
 foreach(HtmlNode link in doc.DocumentElement.SelectNodes("//div[@class='hello']")
 {
    //code
 }

3
无法运行。原作者尝试查找所有类名中包含指定单词(例如“hello”)的 div 元素。而你仅选择类名为“hello”的 div 元素。请修改代码以涵盖所有目标元素。 - Tim Schmelter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接