如何点击 Puppeteer 中的弹出内容?

How to click on popup contents in Puppeteer?

我打开 'deliver to' 弹出窗口,但无法单击输入字段并输入信息。

(async () => {
    const browser = await puppeteer.launch({headless: false});
    const page = await browser.newPage();
    const url = 'https://www.tntsupermarket.com/eng/store-flyer';
    await page.goto(url, {waitUntil: 'networkidle0'});

    const newPagePromise = new Promise(x => browser.once('targetcreated', target => x(target.page())));
    await page.evaluate(()=> {
        document.querySelector('span[class="deliverCss-city-FJJ"]').click();
    });
    const popup = await newPagePromise;
    await popup.waitForSelector('input[aria-label="Enter your Postal Code"]');
    await popup.focus('input[aria-label="Enter your Postal Code"]');
    await popup.click('input[aria-label="Enter your Postal Code"]');
    await popup.keyboard.type('a2b');

})();

pop-up 不是一个新页面,只是一个用 JS 显示但没有导航的模态元素。删除导航承诺会得到一个非常清晰的结果:

const puppeteer = require("puppeteer"); // ^13.5.1

let browser;
(async () => {
  browser = await puppeteer.launch({headless: false});
  const [page] = await browser.pages();
  const url = "https://www.tntsupermarket.com/eng/store-flyer";
  await page.goto(url, {waitUntil: "networkidle0", timeout: 90000});
  const cityEl = await page.waitForSelector('span[class="deliverCss-city-FJJ"]');
  await cityEl.evaluate(el => el.click());
  const postalSel = 'input[aria-label="Enter your Postal Code"]';
  const postalEl = await page.waitForSelector(postalSel);
  await postalEl.type("a2b");
  await page.waitForTimeout(30000); // just to show that the state is as we wish
})()
  .catch(err => console.error(err))
  .finally(() => browser?.close())
;

这有点慢;有一个烦人的 pop-up 你可能希望点击关闭而不是使用 "networkidle0":

// ... same code
  await page.goto(url, {waitUntil: "domcontentloaded", timeout: 90000});
  const closeEl = await page.waitForSelector("#closeActivityPop");
  await closeEl.click();
  const cityEl = await page.waitForSelector('span[class="deliverCss-city-FJJ"]');
// same code ...

快速浏览一下,如果页面被缓存,pop-up 可能不会显示,因此您可能想在 30 秒左右后中止 page.waitForSelector("#closeActivityPop"); 并继续执行代码而不点击它,取决于您希望脚本的灵活性。