首页 > 解决方案 > Puppeteer 第二个 Promise.all 在尝试使用类 clickable-row 单击 td 后超时

问题描述

我正在尝试使用 Puppeteer 从网站中提取一些数据。脚本需要输入一个表单,提交它,点击一个可点击的行,然后在另一个表中找到数据。前两个步骤完美运行,但是当尝试单击带有类可点击行(或嵌套在其中的 a)的 td 时,我得到了一个奇怪的结果。如果我正在运行 Chromium headless:false 链接会单击,但随后所有操作都停止在页面上运行(例如,在截断的代码中,我尝试再次输入表单)。我试过点击td后截图,结果连第三页都没有截图,而是第二页(貌似链接没有被点击),过一会提示错误

“{ TimeoutError: Promise.then (/IMM2/node_modules/puppeteer/lib/cjs/puppeteer/common/LifecycleWatcher.js:106:111) 的导航超时时间超过 30000 毫秒 名称: 'TimeoutError' }”

我也尝试过使用,await page.waitForNavigation({waitUntil: 'networkidle0',timeout:0});但也没有用。

这是代码:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless : false });
  const listaFirme = `https://www.listafirme.ro/`
  const page = await browser.newPage();
  await page.goto(listaFirme, {waitUntil: 'networkidle2'});
  
  await page.type('input[name=searchfor]', '35629144');

    await Promise.all ([
     page.click('.input-group-btn .btn'),
     page.waitForNavigation(),
 ]).catch(e=> console.log(e))

await Promise.all ([
    page.click('.content table tbody tr:nth-child(even) .clickable-row a'),
    page.waitForNavigation(),
]).catch(e=> console.log(e))

await Promise.all ([
    page.type('input[name=searchfor]', '35629144'),
    page.waitForNavigation(),
]).catch(e=> console.log(e))

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

截图澄清:

第一页

第二页

我是 puppeteer 的新手,所以这可能是一个愚蠢的错误,但我已经尝试解决它一段时间了,到目前为止似乎还没有适合我的解决方案。

标签: javascriptnode.jspuppeteer

解决方案


问题是第二次单击会打开一个新页面,因此您需要捕获此页面而不是等待当前页面的导航:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: false });
  const listaFirme = `https://www.listafirme.ro/`;
  const page = await browser.newPage();
  await page.goto(listaFirme, { waitUntil: 'networkidle2' });

  await page.type('input[name=searchfor]', '35629144');

  await Promise.all([
    page.click('.input-group-btn .btn'),
    page.waitForNavigation(),
  ]).catch(e => console.log(e));

  const [newPage] = await Promise.all([
    getNewPage(),
    page.click('.content table tbody tr:nth-child(even) .clickable-row a'),
  ]).catch(e => console.log(e));

  await newPage.waitForSelector('input[name=searchfor]');
  await newPage.type('input[name=searchfor]', '35629144');

  await Promise.all([
    newPage.click('.input-group-btn .btn'),
    newPage.waitForNavigation(),
  ]).catch(e => console.log(e));

  console.log('Done');

  await browser.close();

  function getNewPage() {
    return new Promise((resolve) => {
      browser.on('targetcreated', checkNewTarget);

      function checkNewTarget(target) {
        if (target.type() === 'page') {
          browser.off('targetcreated', checkNewTarget);
          resolve(target.page());
        }
      }
    });
  }
})();

推荐阅读