为什么SeleniumRC CSS定位器可能比XPath慢?

| 我有一些代码可以执行模拟递归树,以使用SeleniumRC从HTML树中抓取内容。我已经使用Xpath和CSS定位器运行代码。 该树表示为一系列嵌套表。如果根本不重要,则某些树内容开始时将不可见,因为分支“已折叠”。对于Xpath和CSS,就可见与不可见而言,树处于相同状态。 为了获得节点值,我的代码以\“ root \”表达式开始,添加\“ branch \”标记,可以为每个连续的同级节点增加该标记,然后使用\“ node \”标记获取文本内容。 都可以,但是使用我想出的CSS表达式要慢得多。 我想这是一种生成定位符表达式的笨拙方法,尽管它对我有用。我只是想弄清楚如何最好地使用CSS来接近使用Xpath所涉及的时代。 循环测试了许多无效的表达式(一直在寻找第n个兄弟姐妹,直到找不到),由于我逐步钻入嵌套表的方式,表达式变得很长。 下面是递归的一些表达式和示例。如果任何人都可以提供关于我正在做的事情的见解,这会使CSS花费比Xpath更长的时间,那将非常有帮助。 我对这种对HTML内容的处理完全是新手,如果您对我从Xpath转到CSS的方式感到有些愚蠢,请这么说。 XPath“令牌”:
final String rootbase = \"//*[contains(@id,\\\"treeBox\\\")]/div\";
// in next string, \"{branchIncrement}\" will be replaced with integer values from 2 to get to text content, and skip graphical elements
final String leveltoken = \"/table/tbody/tr[{branchIncrement}]/td[2]\";
final String nodetoken = \"/table/tbody/tr/td[4]/span\";
CSS“令牌”:
final String rootbase = \"css=[id*=treeBox]>div\";
// in next string, \"{branchIncrement}\" will be replaced with integer values from 2 to get to text content, and skip graphical elements
final String leveltoken = \">table>tbody>tr:nth-child({branchIncrement})>td:nth-child(2)\";
final String nodetoken = \">table>tbody>tr>td:nth-child(4)>span\";
\“ root \”处内容的第一个XPath表达式是:
//*[contains(@id,\"treeBox\")]/div/table/tbody/tr[2]/td[2]/table/tbody/tr/td[4]/span
具有40个节点树的四个层次的最后XPath表达式是三个层次,每个层次在根(1 + 3 + 3x3 + 3x3x3)之下:
//*[contains(@id,\"treeBox\")]/div/table/tbody/tr[2]/td[2]/table/tbody/tr[2]/td[2]/table/tbody/tr[3]/td[2]/table/tbody/tr[2]/td[2]/table/tbody/tr[2]/td[2]/table/tbody/tr/td[4]/span
第一个CSS表达式是:
[id*=treeBox]>div>table>tbody>tr:nth-child(2)>td:nth-child(2)>table>tbody>tr>td:nth-child(4)>span
最后一个CSS表达式是:
[id*=treeBox]>div>table>tbody>tr:nth-child(2)>td:nth-child(2)>table>tbody>tr:nth-child(2)>td:nth-child(2)>table>tbody>tr:nth-child(3)>td:nth-child(2)>table>tbody>tr:nth-child(2)>td:nth-child(2)>table>tbody>tr:nth-child(2)>td:nth-child(2)>table>tbody>tr>td:nth-child(4)>span
    
已邀请:
在Firefox中,Selenium RC的XPath定位器由浏览器的本机XPath引擎处理,CSS定位器由JavaScript库(Dean Edwards's cssQuery.js)处理。 Selenium的更高版本(例如2.0b *系列)使用jQuery的sizzle库实现CSS,但仍使用JavaScript来实现。除了这种隐含的速度差异外,您还在根表达式(即
[id*=treeBox
)中进行模式匹配,这需要枚举整个DOM树来定位匹配项,甚至在您从那里下降之前也是如此。考虑一下如何用纯JavaScript编写代码,然后您将开始发现问题。 如果让您感觉更好,则IE仍然没有本机XPath实现,因此Selenium在该浏览器中使用了几种JavaScript实现之一,其运行速度是XPath的二分之一到十分之一。因此,在Firefox 3.6中。 长话短说,在这种特殊情况下,您没有什么能做的更快的CSS定位器。     
通常,您无法提供帮助。 Selenium中的XPath选择器机制利用了浏览器的XPath工具。甚至IE6都有其中之一。我不知道通过JavaScript提供CSS选择器工具的浏览器,因此Selenium必须使用自己的代码。由于他们的代码都是JavaScript,内部浏览器XPath解析通常是用本机代码完成的,因此速度要慢得多(尤其是在IE6中)。     
感谢您的反馈。看完您的笔记后,我想知道是否可以通过使用一小段代码来解析文字Id值来替换重复使用的contains表达式,从而获得实质性的改进。 这是我用于同一件事的四个不同的定位器。一对定位器是XPath,两个是CSS。对于这些对中的每对,都使用一个contains表达式,然后首先解析为文字。在每种情况下,示例定位器都用于三级1307节点树的最后一个节点。 包含的XPath:
//*[contains(@id,\"treeBox\")]/div/table/tbody/tr[2]/td[2]/table/tbody/tr[2]/td[2]/table/tbody/tr[2]/td[2]/table/tbody/tr[26]/td[2]/table/tbody/tr/td[4]/span
文字替换的XPath包含表达式:
id(\'ns_7_5R4GAB1A0GKQ50IQJQR7VV10M6__treeBox\')/div/table/tbody/tr[2]/td[2]/table/tbody/tr[2]/td[2]/table/tbody/tr[2]/td[2]/table/tbody/tr[24]/td[2]/table/tbody/tr/td[4]/span
CSS包含:
css=[id*=treeBox]>div>table>tbody>tr:nth-child(2)>td:nth-child(2)>table>tbody>tr:nth-child(2)>td:nth-child(2)>table>tbody>tr:nth-child(2)>td:nth-child(2)>table>tbody>tr:nth-child(24)>td:nth-child(2)>table>tbody>tr>td:nth-child(4)>span
文字替换的CSS包含表达式:
css=[id=ns_7_5R4GAB1A0GKQ50IQJQR7VV10M6__treeBox]>div>table>tbody>tr:nth-child(2)>td:nth-child(2)>table>tbody>tr:nth-child(2)>td:nth-child(2)>table>tbody>tr:nth-child(2)>td:nth-child(2)>table>tbody>tr:nth-child(24)>td:nth-child(2)>table>tbody>tr>td:nth-child(4)>span
通过使用两个不同大小的树(一个102个节点,其他1307个节点),我发现了以下内容。 102个节点:        |包含|文字|  XPath | 15秒| 13秒|   CSS | 19秒| 19秒| 1307个节点:        |包含|文字|  XPath | 255秒| 145秒|   CSS | 1893秒| 1811秒| 显然,本机实现(带有Se-RC的Firefox上的XPath)比JScript实现快得多。需要权衡的是,它可能无法在所有浏览器上正常运行。     

要回复问题请先登录注册