【问题标题】:XPath to first occurrence of element with text length >= 200 characters第一次出现文本长度 >= 200 个字符的元素的 XPath
【发布时间】:2012-03-23 12:09:43
【问题描述】:

如何获取第一个具有 200 个或更多字符的内部文本(纯文本,丢弃其他子项)的元素?

我正在尝试创建一个像 Embed.ly 这样的 HTML 解析器,并且我已经设置了一个备用系统,我首先检查 og:description,然后我会搜索这个事件,然后才搜索 description元标记。

这是因为大多数甚至包含meta description 的网站都在该标记中描述了他们的网站,而不是当前页面的内容。

例子:

<html>
    <body>
        <div>some characters
            <p>200 characters <span>some more stuff</span></p>
        </div>
    </body>
</html>

我可以使用什么选择器来获取该 HTML 片段的 200 个字符 部分?我也不想要更多的东西,我不在乎它是什么元素(&lt;script&gt;&lt;style&gt; 除外),只要它是第一个包含在的纯文本至少 200 个字符。

XPath 查询应该是什么样的?

【问题讨论】:

    标签: c# html xpath html-agility-pack


    【解决方案1】:

    使用

    (//*[not(self::script or self::style)]/text()[string-length() > 200])[1]
    

    注意:如果文档是 XHTML 文档(这意味着所有元素都在 xhrml 命名空间中),上述表达式应指定为:

    (//*[not(self::x:script or self::x:style)]/text()[string-length() > 200])[1]
    

    前缀 "x:" 必须绑定到 XHTML 命名空间 -- "http://www.w3.org/1999/xhtml"(或者许多 XPath API 调用它 -- 命名空间必须是“注册”这个前缀)

    【讨论】:

    • 由于这是一项爬虫服务,我真的不知道文档是否为 XHTML
    • @Nico:那就试试不带前缀——我相信 html 敏捷包不需要这个。
    • 是的,因为任何智能 XPath 引擎都会在找到/选择 第一个(也是唯一必需的)节点后停止评估。您给出的表达式将遍历整个树,因为它选择了 所有 个这样的节点。
    【解决方案2】:

    我的意思是这样的:

    root.SelectNodes("html/body/.//*[(name() !='script') and (name()!='style')]/text()[string-length() > 200]")
    

    似乎工作得很好。

    【讨论】:

    • 这个 XPath 表达式选择 all 这样的文本节点——不仅仅是第一个。这将花费比必要更多的空间和时间。在我的回答中,我提供了一个更精确、更高效的 XPath 表达式。
    【解决方案3】:

    HTML 不是 XML。您不应该使用 XML 解析器来解析 HTML 句点。它们完全是两个不同的东西,当你第一次看到不是格式良好的 XML 的 html 时,你的解析器会阻塞。

    你应该找到一个开源的 HTML 解析器,而不是自己动手。

    【讨论】:

    • 我正在使用HtmlAgilityPack,我不是在尝试解析 HTML,我只是想获取包含至少 200 个字符的 HTML 的第一部分。
    猜你喜欢
    • 2015-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多