【问题标题】:puppeteer : how check if browser is still open and workingpuppeteer:如何检查浏览器是否仍然打开并工作
【发布时间】:2019-02-02 08:42:48
【问题描述】:

我试图在单个浏览器实例中打开多个选项卡,完成后我关闭选项卡,然后每隔 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 仍然是 puppeteer 的对象/实例......当我尝试使用该实例打开选项卡时它不会工作,我得到类似的东西

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

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

【问题讨论】:

  • 您在open_tab() 函数中调用page.close();。我认为这就是它关闭浏览器的原因。
  • 他在问如何判断它是否关闭。不是它关闭的原因。

标签: javascript puppeteer


【解决方案1】:

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

disconnected 事件不会被触发。

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

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

【讨论】:

    【解决方案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();
    })();
    

    结果:

    浏览器已断开连接。

    浏览器已重新连接。

    浏览器已关闭。

    浏览器已重新打开。

    【讨论】:

    • 目前,对我来说,这个解决方案不起作用,只有重新启动应用程序才能工作。
    • 格兰特,你能解释一下如何扩展它,以便在页面关闭时它也重新打开“页面”吗?因此,如果页面关闭,它会重新打开。如果浏览器关闭,它会重新打开浏览器和页面。
    【解决方案3】:

    你可以做一个很简单的函数来判断浏览器进程是否被杀死。

    async function wasBrowserKilled(browser){
      const procInfo = await browser.process();
      return !!procInfo.signalCode; // null if browser is still running
    }
    

    我们可以在这里使用它,

    const browserKilled = await wasBrowserKilled(global_browser);
    if(global_browser === false || browserKilled)
    

    它会检查浏览器是否被杀死,否则会替换它。

    这只是 API 提供的众多方法中的一种。

    这是我用来测试的代码,如果我注释掉 browser.close() 部分,看看输出会如何变化。

    const puppeteer = require('puppeteer');
    
    puppeteer.launch().then(async browser => {
      const page = await browser.newPage();
      // comment out to keep browser open
      await browser.close();
      console.log({browserKilled: await wasBrowserKilled(browser)});
    });
    
    async function wasBrowserKilled(browser){
      const procInfo = await browser.process();
      return !!procInfo.signalCode;
    }
    

    在此处登录,

    ➜  puppeteer-xvfb git:(direct-script) ✗ node temp/interval_tab.js
    { browserKilled: true }
    ➜  puppeteer-xvfb git:(direct-script) ✗ node temp/interval_tab.js
    { browserKilled: false }
    _
    

    这与事件不同。我专门制作了这个 sn-p 来检查这个特定问题的过程,如果需要,您可以在其中检查并运行它。

    请注意,这只会在浏览器以某种方式崩溃/关闭时产生结果。

    【讨论】:

    • thanx 但是procInfo.signalCode 对于打开和关闭的浏览器都是空的
    • 我的最后显示了 SIGKILL for signalCode :/ 告诉我你是如何关闭浏览器/检查它何时崩溃的。
    猜你喜欢
    • 2015-02-21
    • 2023-03-14
    • 2015-06-27
    • 2020-12-12
    • 2015-12-01
    • 2013-12-28
    • 1970-01-01
    • 1970-01-01
    • 2020-03-07
    相关资源
    最近更新 更多