puppeteer:如何检查浏览器是否仍然打开并工作

新手上路,请多包涵

我试图在单个浏览器实例中打开多个选项卡,完成后我关闭选项卡,然后每隔 x 秒重新打开这些选项卡……但我想让浏览器本身保持打开状态,所以我不必登录每个循环中的每个选项卡

所以浏览器保持打开状态,选项卡打开和关闭

这是我的简化代码,请忽略语法错误

var  global_browser = false ;
async function init_puppeteer( settings ) {

    if(global_browser === false )
        global_browser = await puppeteer.launch({headless: false  , args:['--no-sandbox']});

    for(var i = 0  ; i < settings.length ; i++ )
    {
        var setting = settings[i];
        open_tab($setting);
    }
}

 async function open_tab( setting ){
    const page    = await global_browser.newPage();
    // do stuff
    page.close();
}

setInterval(function (){
    init_puppeteer(settings)
}, 50000 );

这是问题所在,有时浏览器崩溃或由于某种原因而关闭,但 global_browser 仍然是一个对象/木偶操纵者的实例……当我尝试打开带有该实例的选项卡时,诅咒它不会工作,并且我得到类似的东西

(node:5720) UnhandledPromiseRejectionWarning: Error: WebSocket is not open: readyState 3 (CLOSED)

这是我的问题,我如何检查并确保我在 global_browser 中有一个工作/打开的 puppeteer 实例?所以我可以创建一个新实例并在前一个关闭时替换它

原文由 hretic 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.8k
2 个回答

使用 browser.on('disconnected')

您可以使用 browser.on('disconnected') 来监听浏览器何时关闭或崩溃,或者是否调用了 browser.disconnect() 方法。

然后,您可以自动重新启动浏览器,并继续您的程序。

以下类将启动浏览器,并在触发 'disconnected' 事件时自动重新启动浏览器:

 class BrowserHandler {
  constructor() {
    const launch_browser = async () => {
      this.browser = false;
      this.browser = await puppeteer.launch();
      this.browser.on('disconnected', launch_browser);
    };

    (async () => {
      await launch_browser();
    })();
  }
}

BrowserHandler.browser 断开连接时将返回 false

此外,以下函数将使您能够强制您的程序等待浏览器完成启动,然后再继续:

 const wait_for_browser = browser_handler => new Promise((resolve, reject) => {
  const browser_check = setInterval(() => {
    if (browser_handler.browser !== false) {
      clearInterval(browser_check);
      resolve(true);
    }
  }, 100);
});


完整示例:

 'use strict';

const puppeteer = require('puppeteer');

/**
 * Class: BrowserHandler
 *     Relaunch Browser when Closed
 *     Return false when Browser is Disconnected
 */

class BrowserHandler {
  constructor() {
    const launch_browser = async () => {
      this.browser = false;
      this.browser = await puppeteer.launch();
      this.browser.on('disconnected', launch_browser);
    };

    (async () => {
      await launch_browser();
    })();
  }
}

/**
 * Function: wait_for_browser
 *     Wait for Browser to Finish Launching
 */

const wait_for_browser = browser_handler => new Promise((resolve, reject) => {
  const browser_check = setInterval(() => {
    if (browser_handler.browser !== false) {
      clearInterval(browser_check);
      resolve(true);
    }
  }, 100 );
});

// Main Program

(async () => {
  // Open Browser

  const browser_handler = new BrowserHandler;

  await wait_for_browser(browser_handler);

  // Open New Page

  let page = await browser_handler.browser.newPage();

  await page.goto('https://www.example.com/');

  // Disconnect and Automatically Reconnect Browser

  browser_handler.browser.disconnect();

  if (browser_handler.browser === false) {
    console.log('The browser has been disconnected.');

    await wait_for_browser(browser_handler);
  }

  console.log('The browser has been reconnected.');

  // Close and Automatically Reopen Browser

  await browser_handler.browser.close();

  if (browser_handler.browser === false) {
    console.log('The browser has been closed.');

    await wait_for_browser(browser_handler);
  }

  console.log('The browser has been reopened.');

  // Force Close Puppeteer

  process.exit();
})();

结果:

浏览器已断开连接。

浏览器已重新连接。

浏览器已关闭。

浏览器已重新打开。

原文由 Grant Miller 发布,翻译遵循 CC BY-SA 4.0 许可协议

如果您只是关闭所有选项卡(或浏览器窗口)但浏览器进程仍然存在(但没有任何窗口)。

disconnected 事件不会被触发。

然后您可以通过以下方式检查所有选项卡是否已关闭:

         if ((await browser.pages()).length === 0) {
          // no tabs opening, do stuff
        }

原文由 Anyany Pan 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏