Puppeteer - “请求主机太早了!”

问题描述 投票:0回答:1

我使用 Puppeteer 创建了一个函数来检查用户是否已登录。基本上,它首先检查浏览器、页面是否打开,然后查找选择器,并根据是否找到项目返回 true/false。

export async function checkIfUserIsLoggedIn() {
  const logger = getLogger('checkIfUserIsLoggedIn()');
  try {
    if (!page || !browser) {
      logger.info('page or browser is not open');
      return false;
    }

    logger.info('page or browser is open');
    await delay(randomWaitTimeSeconds1_2());

    // await page.waitForSelector(selector);
    const btn = await page.$(selector);

    logger.info(`user is logged in - ${!!btn ? 'YES' : 'NO'}`);
    return !!btn;
  } catch (e) {
    logError('checkIfUserIsLoggedIn()', e);
  }
}

有时会出现错误“错误:请求主机太早!”当我尝试选择所需元素或等待选择器(上面一行,注释行)时会发生这种情况。 完整错误消息:

[2023-10-02T01:58:06.825] [ERROR] checkIfUserIsLoggedIn() - Error: Requesting main frame too early!
    at assert (C:\Users\simon\Desktop\tb-project-pup\node_modules\puppeteer-core\lib\cjs\puppeteer\util\assert.js:28:15)
    at FrameManager.mainFrame (C:\Users\simon\Desktop\tb-project-pup\node_modules\puppeteer-core\lib\cjs\puppeteer\cdp\FrameManager.js:219:32)
    at CdpPage.mainFrame (C:\Users\simon\Desktop\tb-project-pup\node_modules\puppeteer-core\lib\cjs\puppeteer\cdp\Page.js:407:35)
    at CdpPage.$ (C:\Users\simon\Desktop\tb-project-pup\node_modules\puppeteer-core\lib\cjs\puppeteer\api\Page.js:324:31)
    at checkIfUserIsLoggedIn (file:///C:/Users/simon/Desktop/tb-project-pup/main/checkIfUserIsLoggedIn.js:19:38)

发生这种情况的页面有某种计时器。当计时器转到 00 时,页面会自动重新加载(“?reload = auto”),我认为这会导致错误。但这种情况很少发生。

我试图理解为什么这个错误会导致 Puppeteer 关闭并关闭浏览器?在其他函数中,我有时会收到错误

TimeoutError: Waiting for selector 
.el
 failed: Waiting failed: 30000ms exceeded
,或另一个错误
ProtocolError: Protocol error (DOM.describeNode): Cannot find context with specified id
,但在这些情况下,错误不会关闭浏览器,但这个会关闭。

也许有人可以帮助我理解为什么 puppeteer 被关闭?还帮我找到正确的解决方案吗?

我想也许在

const btn = await page.$(selector);
之前我可以添加类似的内容
await page.waitForNavigation({ waitUntil: 'domcontentloaded', });
但导航并不经常发生,页面重新加载可能需要 2 分钟以上的时间。 另外我在想也许我可以引入另一个 try catch 块来在发生错误时重新运行此函数,例如: (但是如果我这样做,我还需要原来的 try/catch 块吗?)

const anchorElement = await page.$(selector).catch(async () => {
      retryCount++;
      if (retryCount < 3) {
        await checkIfUserIsLoggedIn();
       // OR await page.$(selector)
      }
    });

javascript error-handling puppeteer browser-automation
1个回答
0
投票

page.$不会等待,你想要page.waitForSelector:

let loggedIn = await page.waitForSelector('[href*=logout]', { timeout: 10000 }).catch(e => {})
© www.soinside.com 2019 - 2024. All rights reserved.