如何在 Puppeteer 中单击带有文本的元素 [英] How to click on element with text in Puppeteer

查看:98
本文介绍了如何在 Puppeteer 中单击带有文本的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

例如我有 html:

<button>按钮文本</button><a href=#>Href 文本</a><div>Div 文本</div>

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

Page.click('按钮文本', '.elements')

解决方案

简短回答

此 XPath 表达式将查询包含文本Button text"的按钮:

const [button] = await page.$x("//button[contains(., 'Button text')]");如果(按钮){等待 button.click();}

要同时尊重按钮周围的

,请使用以下代码:

const [button] = await page.$x("//div[@class='elements']/button[contains(., 'Button text')]");

说明

为了解释为什么在某些情况下使用文本节点(text())是错误的,让我们看一个例子:

<button>开始 结束</button><button>开始 <em>中间</em>结束

首先我们来看看使用contains(text(), 'Text')时的结果:

  • //button[contains(text(), 'Start')] 将返回两个两个节点(如预期)
  • //button[contains(text(), 'End')] 只会返回一个节点(第一个)作为text() 返回一个包含两个文本的列表(Start End),但 contains 只会检查第一个
  • //button[contains(text(), 'Middle')] 将返回 no 结果,因为 text() 不包括子节点的文本

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

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

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

Is there any method (didn't find in API) or solution to click on element with text?

For example I have html:

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

And I want to click on element in which text is wrapped (click on button inside .elements), like:

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

解决方案

Short answer

This XPath expression will query a button which contains the text "Button text":

const [button] = await page.$x("//button[contains(., 'Button text')]");
if (button) {
    await button.click();
}

To also respect the <div class="elements"> surrounding the buttons, use the following code:

const [button] = await page.$x("//div[@class='elements']/button[contains(., 'Button text')]");

Explanation

To explain why using the text node (text()) is wrong in some cases, let's look at an example:

<div>
    <button>Start End</button>
    <button>Start <em>Middle</em> End</button>
</div>

First, let's check the results when using contains(text(), 'Text'):

  • //button[contains(text(), 'Start')] will return both two nodes (as expected)
  • //button[contains(text(), 'End')] will only return one nodes (the first) as text() returns a list with two texts (Start and End), but contains will only check the first one
  • //button[contains(text(), 'Middle')] will return no results as text() does not include the text of child nodes

Here are the XPath expressions for contains(., 'Text'), which works on the element itself including its child nodes:

  • //button[contains(., 'Start')] will return both two buttons
  • //button[contains(., 'End')] will again return both two buttons
  • //button[contains(., 'Middle')] will return one (the last button)

So in most cases, it makes more sense to use the . instead of text() in an XPath expression.

这篇关于如何在 Puppeteer 中单击带有文本的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆