简短回答
这个XPath表达式将查询一个包含文本“Button text”的按钮:
const [button] = await page.$x("//button[contains(., 'Button text')]");
if (button) {
await button.click();
}
要同时尊重包围按钮的<div class="elements">
,请使用以下代码:
const [button] = await page.$x("//div[@class='elements']/button[contains(., 'Button text')]");
解释
为了解释在某些情况下使用文本节点(text()
)是错误的,让我们看一个例子:
<div>
<button>Start End</button>
<button>Start <em>Middle</em> End</button>
</div>
首先,让我们来看一下使用contains(text(),'Text')
的结果:
//button[contains(text(),'Start')]
会返回两个节点(如预期)
//button[contains(text(),'End')]
只会返回一个节点(第一个),因为text()
返回一个包含两个文本(Start
和 End
)的列表,但是contains
只会检查第一个文本
//button[contains(text(),'Middle')]
不会返回任何结果,因为text()
不包括子节点的文本
这里是适用于contains(.,'Text')
的XPath表达式,它可以作用于元素本身及其子节点:
//button[contains(.,'Start')]
将返回两个按钮
//button[contains(.,'End')]
再次返回两个按钮
//button[contains(.,'Middle')]
将返回一个按钮(最后一个按钮)
所以在大多数情况下,在XPath表达式中使用.
而不是text()
更有意义。