XPath 还是 querySelector?

Posted

技术标签:

【中文标题】XPath 还是 querySelector?【英文标题】:XPath or querySelector? 【发布时间】:2010-11-06 23:47:48 【问题描述】:

XPath 可以做所有 querySelector 可以做的事情,甚至更多,那么你什么时候会选择后者呢?我还没有看到任何速度基准比较这两者,所以现在我根据语法简洁性进行选择,这似乎有点随意。

编辑:我可能应该说我正在为 Firefox 编写 Greasemonkey 脚本,所以我不担心跨浏览器的兼容性,并且宁愿不包含任何库。

【问题讨论】:

他们不是完全不同的两个东西吗?我认为 querySelector 用于 CSS 选择器,而 XPath 用于 XML 节点/属性。 CSS 和 XPath 选择器都在 DOM 上运行,并且由于 XML 和 html 文档都是根据文档对象模型定义的,因此现在您可以同时使用这两种选择器,这要感谢 querySelector*document.evaluate。不过,在落后的 IE 世界(甚至包括 IE10)中,HTML 文档仍然没有原生 XPath 支持。 【参考方案1】:

你用的是什么浏览器?在 Safari(或 iPhone)中,querySelector 和 querySelectorAll 比 XPath 快得多。 IE 根本不支持 XPath,IE6 和 IE7 也不支持 querySelector。最快的跨浏览器选择器引擎是 Sizzle,由 John Resig 创建。 Sizzle 也是 jQuery 中使用的主要选择器引擎。它在适当的地方使用 querySelector,在 querySelector 不可用的地方使用普通的 DOM 方法。

【讨论】:

XPath 比 Chrome 35.0.1916.153 m、Opera 24.0.1555.0(都带有 Blink 引擎)中的 querySelectorAll 快得多,但在运行此测试时 querySelectorAll 比 Firefox 30.0 中的 XPath 快得多:jsperf.com/xpath-vs-queryselectorall .所以它真的取决于所使用的浏览器——这可能是一个相关的观点,例如在不使用任何外部库的情况下开发浏览器扩展......但前提是那些毫秒真的确实很重要,我认为这是一种相对罕见的情况。【参考方案2】:

就功能而言,您最好的选择是使用包含选择器引擎的库,其中许多(例如 MooTools、Dojo、Prototype)已经在内部使用 XPath 来执行某些类的查询。您应该能够依靠一个好的图书馆为您选择禁食方法。

XPath 可能能够做所有 querySelector 能做的事情(我认为这个说法有点可疑,但这是题外话)但是 querySelector 和 querySelectorAll 并不是所有浏览器都支持,所以我们真的应该将 XPath 与原生 DOM 查询方法(即 getElementsByTagName、getElementById、querySelector、标准遍历和过滤方法等)

使用原生 DOM 过滤方法需要了解浏览器的怪癖和限制,并且对于复杂的查询很快变得不切实际,除非您使用库(例如 jQuery 或 MooTools)来消除不一致。原生 DOM 技术(无论是通过像 jQuery 这样的代理还是自定义实现)通常被选择而不是 XPath 的原因是它们确实提供了比 XPath 更大的灵活性。例如,如果您想过滤已检查的输入,“隐藏”元素或禁用输入 XPath 很短,但 jQuery 为您提供 :checked、:hidden 和 :disabled 伪类。

【讨论】:

【参考方案3】:

如果您还没有学习过 XPath 但只知道 CSS 选择器,则只能使用 querySelector。除此之外,即使对于简单的查询,XPath 语法也可能更复杂。因此,如果您不需要 XPath 提供的功能,使用 CSS 选择器可能会更容易。

你应该注意两件事:

id 选择器在纯 XML 上使用时不能与 querySelector 一起使用(或者至少不可靠) querySelector 仅适用于浏览器当前支持的选择器,因此如果它不支持某些 CSS3 选择器,您将无法使用这些选择器。

【讨论】:

【参考方案4】:

CSS 语法很棒有两个原因:

与更复杂的 XPath 相比,它的速度要快一个数量级,并且占用的资源更少。 当您想要查找的内容可以通过 css 选择器找到时,执行相同操作的相应 XPath 查询通常会更长且更难阅读。

举个例子:使用这个 css 选择器:h1.header > a[rel~="author"]

它的最短功能 XPath 等效//h1[contains(" "+normalize-space(@class)+" "," header ")]/a[contains(" "+normalize-space(@rel)+" "," author ")]

…阅读和写作都更难。

如果您改为编写此 XPath://h1[@class="header"]/a[@rel="author"]

…你会错误地错过<h1 class="article header"><a rel="author external" href="/mike">...</a></h1>这样的标记

当你真的需要 XPath 时,它是唯一的选择,除非你想用代码手动遍历 DOM(这会变得非常快)。

就我个人而言(我是 Greasemonkey 的维护者之一),我使用非常小的 on.js 库来满足我所有的节点切片需求——它为我提供了 XPath(当我需要时)和 CSS 的组合(我几乎一直都倾向于使用它)——主要是因为它让我可以将处理挖掘我需要消化的页面部分的所有代码分离到脚本标题中,这样我的代码就可以得到它需要的所有东西,并且可以真正为网页做一些有趣或伟大的事情。

Web 浏览器为非常快速地运行 javascript 进行了高度优化,如果我是你,我建议使用让你作为开发人员最高效和最快乐的东西,而不是让浏览器运行最少的代码的东西。不过,on.js 的一个附带好处尤其是,它会自动帮助脚本通常根本无法运行,在您认为 存在的节点的页面上,结果没有 是,而不是破坏页面。

【讨论】:

以上是关于XPath 还是 querySelector?的主要内容,如果未能解决你的问题,请参考以下文章

如何根据元素的className获取元素?

Python爬虫(十三)_案例:使用XPath的爬虫

如何在 xpath 表达式上执行“或”而不用“|”连接两个 xpath还是使用 xpath 函数?

如何使用量角器或selenium在网页中的Shadow-root下的文本框中输入文本。

querySelector和getElementsBy系列的区别

querySelector和getElementsBy系列的区别