English 中文(简体)
你们如何点击在Popppeteer的一段内容?
原标题:How do you click on an element with text in Puppeteer?

是否有任何办法或解决办法可点击带有文字的内容? 我看不到APIC。

For example I have the following HTML:

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

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

Page.click( Button text ,  .elements )
最佳回答

Short answer

这份XPath的表述将质疑一个包含“Button文本”的纽芬兰语:

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

解释为什么使用案文节点(>条形码(>>>)在某些情况下是错误的,请举一个例子:

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

首先,请在使用<代码>contains(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

The XPath expression for contains (, Text ), which work on the content se 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)

因此,在大多数情况下,在XPath的表述中使用<代码>>而不是text(>更有意义。

问题回答

也可使用

await page.evaluate(() => {
  [...document.querySelectorAll( .elements button )].find(element => element.textContent ===  Button text ).click();
});

Alternatively, you can use page.evaluate() to click an element based on its text content using document.evaluate() and a corresponding XPath expression:

await page.evaluate(() => {
  const xpath =  //*[@class="elements"]//button[contains(text(), "Button text")] ;
  const result = document.evaluate(xpath, document, null, XPathResult.ANY_TYPE, null);

  result.iterateNext().click();
});

快速解决,以便能够使用先进选用器,如“:内容”

http://www.npmjs.com/ Package/puppeteer-select"rel=“noretinger”>library 你们

const select = require ( puppeteer-select );

const element = await select(page).getElement( button:contains(Button text) );
await element.click()

Puppeteer 19.7.1 添加p(pseudo) 挑选人,因此,text/ 作了解释,支持:-p-text,其中选取代号。 例如:

const el = await page.waitForSelector("::-p-text(Button text)");

Pseudoselectors can work in conjunction with CSS selectors, like

const el = await page.$(".elements button::-p-text(Button text)");

在Popetepper >=18.0.0中,选修人拥有>text/。 选择要素案文的序号:

const el = await page.waitForSelector("text/Button text");

具体来说,与18年前相比,XPath最为相关。 Puppeteer:

由于欧佩斯的使用案例似乎与目标载体(<条码>)“Button”文本(、<button>Button text</button>text(>)似乎与正确方法不同,而不是<条码>contains()。

虽然,但Thomas为contains提供了良好的论据。 如果有子,则使用<代码>text(>>>,避免产生错误的负面效应,则当纽特(<button>Button text and more uff</button>, 似乎也是一种假想。 拥有这两种工具是有益的,以便你能够逐案选择更适当的工具。

const xp =  //*[@class="elements"]//button[text()="Button text"] ;
const [el] = await page.$x(xp);
await el?.click();

请注意,其他许多答复都忽略了<代码>.elements other category要求。

另一个XPath功能是[normalize-space()=“Button text”。 那些“从地体中引导和跟踪白色空间,用单一空间取代白空间的序列”,对某些情况可能有用。

此外,它经常使用waitForXPath。 如果XPath没有在规定时限内找到,则等待,然后返回:

const xp =  //*[@class="elements"]//button[text()="Button text"] ;
const el = await page.waitForXPath(xp);
await el.click();

在各种环境中运作的另一种灵活做法是使用浏览器S-.find(.filter(>,在案文中列出了你想要的内容:

// untrusted click (ignores visibility, sometimes useful):
await page.$$eval(".elements *", els =>
  els
    .find(el => el.textContent.trim().toLowerCase() === "button text")
    .click()
);

// trusted click:
const el = await page.evaluateHandle(() =>
  [...document.querySelectorAll(".elements *")]
    .find(el => el.textContent.trim().toLowerCase() === "button text")
);
await el.click();

// untrusted clicks
const els = await page.$$eval(".elements *", els =>
  els
    .filter(el => el.textContent.trim().toLowerCase() === "button text")
    .forEach(el => el.click())
);

// trusted clicks (not ideal)
const els = await page.evaluateHandle(`
  [...document.querySelectorAll(".elements *")]
    .filter(el => el.textContent.trim().toLowerCase() === "button text")
`);
const length = await els.evaluate(els => els.length);

for (let i = 0; i < length; i++) {
  const el = await els.evaluateHandle((els, i) => els[i], i);
  await el.click();
}

如果您需要等待这一案文,请您使用<>互换功能:

const el = await page.waitForFunction(`
  [...document.querySelectorAll(".elements *")]
    .find(el => el.textContent.trim().toLowerCase() === "button text")
`);
await el.click();

如果你重新操纵一页,而那页的 j(或如果你 进口,则你可以使用<代码>:contains<>>:ttains sizzle pseumedlector syntax:

const el = await page.evaluateHandle(`
  $( .elements :contains("Button text") ).first()
`);

The solution is

(await page.$$eval(selector, a => a
            .filter(a => a.textContent ===  target text )
))[0].click()

我的解决办法是:

let selector =  a ;
    await page.$$eval(selector, anchors => {
        anchors.map(anchor => {
            if(anchor.textContent ==  target text ) {
                anchor.click();
                return
            }
        })
    });

文本选择或合并选择没有经过支持的专栏,因此我的工作是:

await page.$$eval( selector , selectorMatched => {
    for(i in selectorMatched)
      if(selectorMatched[i].textContent ===  text string ){
          selectorMatched[i].click();
          break;//Remove this line (break statement) if you want to click on all matched elements otherwise the first element only is clicked  
        }
    });

用12.0.1页,我的工作如下:

await page.click("input[value= Opt1 ]"); //where value is an attribute of the element input
await page.waitForTimeout(1000);

await page.click("li[value= Nested choice 1 ]"); //where value is an attribute of the element li after clicking the previous option
await page.waitForTimeout(5000);




相关问题
CSS working only in Firefox

I am trying to create a search text-field like on the Apple website. The HTML looks like this: <div class="frm-search"> <div> <input class="btn" type="image" src="http://www....

image changed but appears the same in browser

I m writing a php script to crop an image. The script overwrites the old image with the new one, but when I reload the page (which is supposed to pickup the new image) I still see the old one. ...

Firefox background image horizontal centering oddity

I am building some basic HTML code for a CMS. One of the page-related options in the CMS is "background image" and "stretch page width / height to background image width / height." so that with large ...

Separator line in ASP.NET

I d like to add a simple separator line in an aspx web form. Does anyone know how? It sounds easy enough, but still I can t manage to find how to do it.. 10x!

热门标签