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,如果你担心的话。
我对 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,如果你担心的话。