C#Html Agility Pack解析具有多个备选方案的标签

c# html html-agility-pack tags

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

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

我想获取表单的所有字符串:

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

所以我的选择参数是

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

但是,这也会导致返回字符串,例如

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

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

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

有人可以建议正确的方法来做到这一点。谢谢!

一般承认的答案

搜索img标签,只需要在同一级别找到src ,不一定就在img标签旁边

您似乎想要找到<img>元素,其中src属性是第一个属性。请注意,XML / HTML解析器不必保留属性顺序,因此通常您不希望根据特定属性顺序选择元素,即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);
}

输出:

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);
}

*)XPath已经过滤了具有属性src img元素,因此如果您担心, Attributes[0].Name将永远不会产生NRE。


热门答案

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

以下控制台项目代码段将仅返回您想要的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



许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因
许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因