gpt4 book ai didi

c# - HtmlAgilityPack NextSibling.InnerText 值为空

转载 作者:行者123 更新时间:2023-11-30 19:26:04 24 4
gpt4 key购买 nike

我正在使用 HtmlAgilityPack 抓取一些数据。

HTML 看起来像这样:

<div id="id-here">
<dl>
<dt> Field Name </dt>
<dd> Value for above field name </dd>
<dt> Field Name </dt>
<dd> Value for above field name </dd>
<dt> Field Name </dt>
<dd> Value for above field name </dd>
</dl>
</div>

现在我遇到的问题是,并不总是有一定数量的字段,所以我无法像这样可靠地访问每个字段:

//*[@id="id-here"]/dl[1]/dd[1]

因为 dd[1] 在一个页面上可能是一个名字,而在另一个页面上可能是一个电话,其中用户未能填写姓名,因此字段被隐藏。

所以我像这样获取所有 DT 和 DD 节点:

//*[@id="id-here"]/dl[1]/dt | //*[@id="id-here"]/dl[1]/dd

现在我检查每个节点,看看它是否匹配我想要的字段,并像这样获取 NextSibling 值:

    foreach (HtmlNode node in details)
{
if (node.InnerText.Contains("Tel:")) telephone = node.NextSibling.InnerText;
if (node.InnerText.Contains("Email:")) email = node.NextSibling.InnerText;
}

这适用于电话,但由于某种原因,当“电子邮件:”节点出现时,NextSibling.InnerHTMLNextSibling.InnerText 都是空白的,尽管下一个兄弟肯定有数据。如果我真的转到 details 中的那个 node 并查看它,InnerHTML 是整个格式化链接和 InnerText 是电子邮件地址。

NextSibling.InnerText 是否因为 A 标签使其成为子标签或其他原因而无法正常工作?我查看了调试器,但在 NextSibling 下找不到我需要的信息。

我敢肯定答案简单得离谱,我就是想不通。有人让我摆脱痛苦吗?

最佳答案

发生这种情况的原因是如果nodedt与其对应的 dd 分开的元素由一些空格组成的元素,然后是 node.NextSibling是一个全空白文本节点(</dt><dd> 之间的空格)。如果你在调试器中查看它,你会看到 node.NextSiblingNodeTypeHtmlNodeType.Text而不是 HtmlNodeType.Element .

我建议创建一个方便的方法来获取 dt 的文本节点对应的dd :

internal static string GetMatchingDdValue(HtmlNode dtNode)
{
var found = dtNode.SelectSingleNode("following-sibling::*[1][self::dd]");
return found == null ? "" : found.InnerText;
}

然后你可以像这样使用它:

if (node.InnerText.Contains("Tel:")) { telephone = GetMatchingDdValue(node); }

下面是我上面的方法中使用的有点棘手的 XPath 的分割:

(a) following-sibling::*

^ 选择所有共享相同的元素 父节点作为当前节点并出现在它之后。

(b) following-sibling::*[1]

^ 选择集合(a)中的第一个节点 (如果有的话)

(c) following-sibling::*[1][self::dd] 

^ 选择集合 (b) 中的所有节点 是名为“dd”的元素

SelectSingleNode()选择集合 (c) 中的第一个节点,它应该始终是 1 个或 0 个节点。

你很可能只需要 following-sibling::ddfollowing-sibling::* ,但上述路径包含保障措施。例如,如果出于某种原因,您有以下 XML,并且您的当前节点是 Tel:元素:

<dl>
<dt>Tel:</dt>
<dt>Address:</dt>
<dd>50 Fake St.</dd>
</dl>

following-sibling::dd会给你结果“50 Fake St.”,而 following-sibling::*会给你结果“地址:”。相反,following-sibling::*[1][self::dd]在这种情况下会选择一个空节点集,因此该方法会正确地生成一个空字符串作为结果。

关于c# - HtmlAgilityPack NextSibling.InnerText 值为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25535284/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com