如何在 Puppeteer 中单击带有文本的元素

新手上路,请多包涵

是否有任何方法(在 API 中找不到)或解决方案来单击带有文本的元素?

例如我有html:

 <div class="elements">
    <button>Button text</button>
    <a href=#>Href text</a>
    <div>Div text</div>
</div>

我想单击包含文本的元素(单击.elements 内的按钮),例如:

 Page.click('Button text', '.elements')

原文由 Aleksandr Golubovskij 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.8k
2 个回答

简短的回答

此 XPath 表达式将查询包含文本“按钮文本”的按钮:

 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')] will only return one nodes (the first) as text() returns a list with two texts ( Start and End ), but contains 只会检查第一个
  • //button[contains(text(), 'Middle')] 将不返回 任何 结果,因为 text() 不包括子节点的文本

以下是 contains(., 'Text') 的 XPath 表达式,它适用于元素本身,包括其子节点:

  • //button[contains(., 'Start')] 将返回 两个 按钮
  • //button[contains(., 'End')] 将再次返回 两个 按钮
  • //button[contains(., 'Middle')] 将返回 一个(最后一个按钮)

所以在大多数情况下,在 XPath 表达式中使用 . 而不是 text() 更有意义。

原文由 Thomas Dondorf 发布,翻译遵循 CC BY-SA 4.0 许可协议

您可以只使用查询选择器。

 await page.evaluate(() => {
    document.querySelector('input[type=button]').click();
});

编辑—-

您可以给按钮一个 className 并使用它来选择按钮元素,因为您确切知道要单击的内容:

 await page.evaluate(() => {
    document.querySelector('.button]').click();
});

原文由 Esther 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题