C# Html Agility Pack 解析具有多种选择的标签

C# Html Agility Pack parsing tags with multiple alternatives

我对 HTML 没有任何经验,所以请原谅任何不正确的术语。

我正在尝试使用 HTML Agility Pack 解析 HTML 文档,我正在寻找一个非常具体的字符串。

我想获取以下形式的所有字符串:

<img src="..." etc=....">

所以我的select参数是

HtmlNodeCollection images = doc.DocumentNode.SelectNodes("//img[@src]");

然而,这也会返回字符串,例如

<img width="..." src="..." etc="..">

在我看来(至少据我所知):搜索img标签,只需要在同一层找到src,不一定就在img标签旁边。

在查看文档后,我觉得我正在尝试做一些我不允许使用此功能做的事情。

有人可以建议正确的方法吗?谢谢!

我不熟悉 XPATH,所以我假设你的是正确的(除了 HtmlAgilityPack 之外,我通常使用 css 使用 ScrapySharp 库的选择器)。

以下控制台项目代码片段将 return 只有您想要的 img 节点,即仅具有 2 个属性的节点 - src 等,不多不少。 我手动加载了一个包含 3 个图像节点的示例 html,如下所示:

        HtmlDocument doc = new HtmlDocument();
        string html = @"
            <img src='img1.jpg' />
            <img src='img1.jpg' etc='etcValue' />
            <img width='200px' src='img1.jpg' />
        ";
        doc.LoadHtml(html);

        var relevantImgNodes = doc.DocumentNode.SelectNodes("//img")
            .Where(n => 
                n.Attributes.Count == 2 && 
                !string.IsNullOrEmpty(n.GetAttributeValue("src")) && 
                !string.IsNullOrEmpty(n.GetAttributeValue("etc")));

        Console.WriteLine(relevantImgNodes.Count()); // prints 1

"The img tag is searched for and src only needs to be found on the same level, not necessarily right next to the img tag."

您似乎想要查找 <img> 元素,其中 src 属性是第一个属性。请注意,XML/HTML 解析器不必保留属性顺序,因此通常您不希望 select 元素基于某些属性顺序,即 src 属性首先出现的位置,等等

无论如何,在我过度简化的测试中,HAP 恰好保留了属性顺序,因此使用 Attributes[0].Name* 检查第一个属性的名称也有效:

var raw = @"<div>
    <img src=""..."" etc=""...."">
    <img width=""..."" src=""..."" etc="".."">
    <img>
</div>";
var doc = new HtmlDocument();
doc.LoadHtml(raw);
var result = doc.DocumentNode
                .SelectNodes("//img[@src]")
                .Where(o => o.Attributes[0].Name == "src")
                .ToList();
foreach (var item in result)
{
    Console.WriteLine(item.OuterHtml);
}

输出:

<img src="..." etc="....">

*) XPath 已经过滤了 img 个具有属性 src 的元素,所以 Attributes[0].Name 永远不会产生 NRE,如果你担心的话。