问题:DOM 需要<tbody/>
标签
Firebug、Chrome 的开发者工具、JavaScript 中的 XPath 函数和其他在DOM上工作,而不是在基本的HTML 源代码上工作。
HTML 的 DOM 要求所有不包含在页脚 ( <thead/>
, <tfoot/>
) 的表头中的表行都包含在表体标记<tbody/>
中。因此,如果在解析 (X)HTML 时缺少此标记,浏览器会添加此标记。例如,微软的 DOM 文档说
该tbody
元素对所有表都公开,即使该表没有显式定义tbody
元素。
在 stackoverflow 的另一个答案中有深入的解释。
另一方面,HTML 不一定要求使用该标签:
TBODY
除非表格仅包含一个表格主体且没有表格头部或底部部分,否则始终需要开始标记。
大多数 XPath 处理器处理原始 XML
除了 JavaScript,大多数 XPath 处理器都处理原始 XML,而不是 DOM,因此不添加<tbody/>
标签。HTML 解析器库(如tag-soup和htmltidy)也只输出 XHTML,而不是“DOM-HTML”。
这是在 Stackoverflow 上发布的 PHP、Ruby、Python、Java、C#、Google 文档(电子表格)和许多其他问题的常见问题。Selenium 在浏览器中运行并在 DOM 上运行——所以它不受影响!
重现问题
将 Firebug(或 Chrome 的开发工具)显示的源代码与通过右键单击并选择“显示页面源代码”(或在浏览器中调用的任何名称)或curl http://your.example.org
在命令行中使用的源代码进行比较。后者可能不包含任何<tbody/>
元素(它们很少使用),Firebug 将始终显示它们。
解决方案 1:删除/tbody
Axis Step
检查您遇到的表格是否真的不包含<tbody/>
元素(请参阅最后一段)。如果是这样,您可能遇到了另一种问题。
现在删除/tbody
轴步骤,所以您的查询看起来像
//table[@id="example"]/tr[2]/td[1]
解决方案 2:跳过<tbody/>
标签
这是一个相当肮脏的解决方案,并且对于嵌套表可能会失败(可以跳转到内部表)。我只会在极少数情况下建议这样做。
/tbody
用后代或自我步骤替换轴步骤:
//table[@id="example"]//tr[2]/td[1]
解决方案 3:允许带标签和不带<tbody/>
标签的输入
如果您事先不确定您的表格或在“HTML 源”和 DOM 上下文中使用查询;并且不想/不能使用解决方案 2 中的 hack,提供替代查询(对于 XPath 1.0)或使用“可选”轴步骤(XPath 2.0 和更高版本)。
- XPath 1.0:
//table[@id="example"]/tr[2]/td[1] | //table[@id="example"]/tbody/tr[2]/td[1]
- XPath 2.0:
//table[@id="example"]/(tbody, .)/tr[2]/td[1]