Node.js 为什么木偶演员要报道;未处理的PromisejectionWarning:错误:导航失败,因为浏览器已断开连接&引用;?
我有一个简单的node.js脚本来捕获一些网页的截图。在使用async/await的过程中,我似乎遇到了一些问题,但我不知道在哪里。我目前使用的是木偶剧v1.11.0Node.js 为什么木偶演员要报道;未处理的PromisejectionWarning:错误:导航失败,因为浏览器已断开连接&引用;?,node.js,puppeteer,google-chrome-headless,Node.js,Puppeteer,Google Chrome Headless,我有一个简单的node.js脚本来捕获一些网页的截图。在使用async/await的过程中,我似乎遇到了一些问题,但我不知道在哪里。我目前使用的是木偶剧v1.11.0 const puppeteer = require('puppeteer'); //a list of sites to screenshot const papers = { nytimes: "https://www.nytimes.com/", wapo: "https://www.washington
const puppeteer = require('puppeteer');
//a list of sites to screenshot
const papers =
{
nytimes: "https://www.nytimes.com/",
wapo: "https://www.washingtonpost.com/"
};
//launch puppeteer, do everything in .then() handler
puppeteer.launch({devtools:false}).then(function(browser){
//create a load_page function that returns a promise which resolves when screenshot is taken
async function load_page(paper){
const url = papers[paper];
return new Promise(async function(resolve, reject){
const page = await browser.newPage();
await page.setViewport({width:1024, height: 768});
//screenshot on first console message
page.once("console", async console_msg => {
await page.pdf({path: paper + '.pdf',
printBackground:true,
width:'1024px',
height:'768px',
margin: {top:"0px", right:"0px", bottom:"0px", left:"0px"}
});
//close page
await page.close();
//resolve promise
resolve();
});
//go to page
await page.goto(url, {"waitUntil":["load", "networkidle0"]});
})
}
//step through the list of papers, calling the above load_page()
async function stepThru(){
for(var p in papers){
if(papers.hasOwnProperty(p)){
//wait to load page and screenshot before loading next page
await load_page(p);
}
}
//close browser after loop has finished (and all promises resolved)
await browser.close();
}
//kick it off
stepThru();
//getting this error message:
//UnhandledPromiseRejectionWarning: Error: Navigation failed because browser has disconnected!
});
导航失败,因为浏览器已断开连接
错误通常意味着启动Puppeter的节点脚本在不等待Puppeter操作完成的情况下结束。因此,正如你所说的,这是一些等待的问题
关于您的脚本,我做了一些更改以使其正常工作:
stepThru
函数的(异步)结束,所以请更改stepThru();
到
wait stepThru();
及
puppeter.launch({devtools:false})。然后(函数(浏览器){
到
puppeter.launch({devtools:false})。然后(异步函数(浏览器){
(我添加了async
)
goto
和页面的方式
新承诺(异步函数(解析、拒绝){
//第一条控制台消息的屏幕截图
page.once(“控制台”,异步()=>{
等待页面.pdf({
路径:纸张+'.pdf',
背景:是的,
宽度:'1024px',
高度:'768px',
保证金:{
顶部:“0px”,
右:“0px”,
底部:“0px”,
左:“0px”
}
});
解决();
});
})
它只有一个职责,就是创建PDF
page.goto
和带有Promise.all的PDF承诺
等待承诺([
page.goto(url,{“waitUntil”:[“load”,“networkidle2”]}),
新承诺(异步函数(解析、拒绝){
//…如上所述创建pdf
})
]);
页面。在承诺之后关闭。全部
等待承诺([
//第页转到
//PDF创建
]);
等待页面。关闭();
解决();
现在它工作了,这里是完整的工作脚本:
const puppeter=require('puppeter');
//要截图的站点列表
康斯特文件=
{
纽约时报:“https://www.nytimes.com/",
wapo:“https://www.washingtonpost.com/"
};
//启动木偶师,在中执行所有操作。然后()处理程序
puppeter.launch({devtools:false})。然后(异步函数(浏览器){
//创建一个load_page函数,该函数返回一个承诺,该承诺在截图时解析
异步函数加载页面(纸张){
const url=论文[论文];
返回新承诺(异步函数(解析、拒绝){
const page=wait browser.newPage();
等待page.setViewport({宽度:1024,高度:768});
等待承诺([
page.goto(url,{“waitUntil”:[“load”,“networkidle2”]}),
新承诺(异步函数(解析、拒绝){
//第一条控制台消息的屏幕截图
page.once(“控制台”,异步()=>{
等待page.pdf({path:paper+'.pdf',printBackground:true,宽度:'1024px',高度:'768px',边距:{顶部:“0px”,右侧:“0px”,底部:“0px”,左侧:“0px”});
解决();
});
})
]);
等待页面。关闭();
解决();
})
}
//单步浏览论文列表,调用上面的load_page()
异步函数stepThru(){
用于(文件中的var p){
if(文件所有权(p)){
//等待加载页面和屏幕截图,然后再加载下一页
等待加载页面(p);
}
}
等待浏览器关闭();
}
等待stepThru();
});
请注意:
- 我将
更改为networkidle0
,因为nytimes.com网站需要很长时间才能进入0网络请求状态(因为广告等)。显然,你可以等待networkidle2
,但这取决于你,这超出了你的问题范围(在这种情况下,增加networkidle0
页面。转到
超时)
网站重定向错误太多,所以我改为www.washingtonpost.com
,但我认为您应该对此进行更多调查。为了测试脚本,我在washingtonpost.com
网站和其他网站上使用了更多次。再次说明:这超出了您的问题范围nytimes
如果您需要更多帮助,请告诉我当系统磁盘已满时,我也遇到了同样的错误。这是一个非常好的详细答案,谢谢!一个问题,您选择立即解析()PDF承诺,而不是将解析放在页面内。once()有什么原因吗回调?这是一个错误,我修复了它。两种方法都有效,但我认为第一种方法只是一个幸运的例子,如果你不在函数中等待,那么你不需要使用
async
,例如async function load\u page(paper)
beenfunction load\u page(paper)