因此浏览器保持打开状态,标签页会打开和关闭
这是我的简化代码,请忽略语法错误
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实例?这样我就可以创建一个新实例,如果上一个实例已关闭,则可以替换它
答案 0 :(得分:3)
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();
})();
结果:
浏览器已断开连接。
浏览器已重新连接。
浏览器已关闭。
浏览器已重新打开。
答案 1 :(得分:1)
您可以创建一个非常简单的函数来了解浏览器进程是否被杀死。
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 }
_
这与事件不同。我专门制作了此代码段,以检查此特定问题的过程,并在此检查并在需要时运行它。
请注意,这只会在浏览器崩溃或以某种方式关闭时产生结果。
答案 2 :(得分:1)
如果您仅关闭所有标签页(或浏览器窗口),但浏览器进程仍然存在(但没有任何窗口)。
disconnected
事件不会被触发。
然后,您可以检查是否通过以下方式关闭了所有标签页:
if ((await browser.pages()).length === 0) {
// no tabs opening, do stuff
}