首页 > 解决方案 > 调用 page.waitForTimeout 后,Puppeteer 无法单击元素

问题描述

我正在使用 Telegram 机器人和 puppeteer 进行练习,因此我决定创建一个机器人来从特定网站订购披萨。

一旦机器人接受了他需要将他输入的数据放置在页面上的顺序,它的外观如下所示:

在此处输入图像描述

这两个字段是跨度,当 puppeteer 单击启用的一个(左)时,他会得到一个输入来完成。然后,当第一个输入完成后,puppeteer 必须对第二个字段执行完全相同的过程:单击<span>标签,将数据放入输入等。

但问题是,在第一个领域的完成和第二个领域的激活之间有一个小的时间间隔。我的机器人无法识别这个差距并立即点击第二个字段的跨度(当然它不起作用)。

这是一个代码片段:

await page.waitForXPath('//*[@id="select2-chosen-2"]', {visible: true})
const [secondSpan] = await page.$x('//*[@id="select2-chosen-2"]')
await secondSpan.click()

当我node bot用这个片段输入时,我没有收到任何错误或警告。但正如我所说,激活第二个字段需要一些时间。我找到了一个函数可以让 puppeeter 在一段时间内停止执行我的代码:page.waitForTimeout().

这里是 puppeteer 文档中的使用示例:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  page.waitForTimeout(1000).then(() => console.log('Waited a second!'));

  await browser.close();
})();

https://pptr.dev/#?product=Puppeteer&version=v10.1.0&show=api-pagewaitfortimeoutmilliseconds

这是我的情况:

await page.waitForXPath('//*[@id="select2-chosen-2"]', {visible: true})
const [secondSpan] = await page.$x('//*[@id="select2-chosen-2"]')

page.waitForTimeout(1500)

await secondSpan.click()

此代码也没有显示任何错误,但也没有单击该字段。当我添加awaitpage.waitForTimeout()得到这个错误:

Error: Node is either not visible or not an HTMLElement

我该如何解决?

标签: javascriptnode.jsasync-awaitpuppeteertelegram-bot

解决方案


所以我只需要输入这段代码:

await page.click('#s2id_home-number-modal')

或使用 XPath:

const [secondSpan] = await page.$x('//*[@id="select2-chosen-2"]')
await secondSpan.click()

into.then()方法,即在之后调用page.setTimeout(500)。总而言之,它看起来像这样(顺便说一下,我已经更改了一些选择器,但这没什么大不了的):

await page.waitForTimeout(500).then(async () => {
   await page.click('#s2id_home-number-modal')
})

推荐阅读