Puppeteer:停留在页面上太久会关闭浏览器(协议错误(Runtime.callFunctionOn):会话已关闭。很可能页面已关闭)

Puppeteer: Staying on page too long closes the browser (Protocol error (Runtime.callFunctionOn): Session closed. Most likely the page has been closed)

我的计划是连接到一个页面,与其元素交互一段时间,然后等待并重新开始。由于访问页面的过程比较复杂,我最好只登录一次,然后永久停留在页面上。

index.js

const puppeteer = require('puppeteer');
const creds = require("./creds.json");

(async () => {
    try {
        const browser = await puppeteer.launch();
        const page = await browser.newPage();
        await page.goto('https://www.online-messenger.com');

        await goToChats(page);
        await page.waitForSelector('div[aria-label="Chats"]');

        setInterval(async () => {
            let index = 1;
            while (index <= 5) {
                if (await isUnread(page, index)) {
                    await page.click(`#local-chat`);
                    await page.waitForSelector('div[role="main"]');

                    let conversationName = await getConversationName(page);
                    if (isChat(conversationName)) {
                        await writeMessage(page);
                    }
                }
                index++;
            }
        }, 30000);
    } catch (e) { console.log(e); }
    await page.close();
    await browser.close();
})();

同样,我不想关闭连接,所以我认为添加 setInterval() 会帮助我解决这个问题。 核心代码工作得非常好,但是每次我运行带有间隔函数的代码我都会得到这个错误:

Error: Protocol error (Runtime.callFunctionOn): Session closed. Most likely the page has been closed.

我对代码的主要部分进行了计时,通常需要 20-25 秒左右。我认为问题出在延迟设置为 30 秒,但即使我将它增加到例如60000(60 秒)。

我做错了什么?为什么 setInterval 不起作用,是否有其他方法可以解决我的问题?

好吧,在花了更多时间解决这个问题后,我意识到确实是 setInterval 函数导致了所有错误。

该代码是异步的,为了使其全部正常工作,我不得不使用 setInterval() 的“async”版本。我将我的代码包装在一个无限循环中,它以 promise 结束,它在指定时间后解析。

...

  await goToChats(page);
  await page.waitForSelector('div[aria-label="Chats"]');

  while(true) {
    let index = 1;
    while (index <= 5) {

    if (await isUnread(page, index)) {
      await page.click(`#local-chat`);
      await page.waitForSelector('div[role="main"]');

      let conversationName = await getConversationName(page);
      if (isChat(conversationName)) {
        await writeMessage(page);
      }
    }
    waitBeforeNextIteration(10000);
    index++;
   }
   
...
waitBeforeNextIteration(ms) {
  return new Promise(resolve => setTimeout(resolve, ms))
}