Ошибка Navigation failed because browser has disconnected
обычно означает, что сценарии узла, запустившие Puppeteer, заканчиваются, не дожидаясь завершения действий Puppeteer.Следовательно, это проблема с некоторыми ожиданиями, как вы сказали.
О вашем скрипте я внес некоторые изменения, чтобы он работал:
1 - во-первых, вы не ожидаете(асинхронный) конец функции stepThru
, поэтому измените
stepThru();
на
await stepThru();
и
puppeteer.launch({devtools:false}).then(function(browser){
на
puppeteer.launch({devtools:false}).then(async function(browser){
(Я добавил async
)
2 - я изменил способ управления обещаниями goto
и pagce.once
Обещание в формате PDF теперь
new Promise(async function(resolve, reject){
//screenshot on first console message
page.once("console", async () => {
await page.pdf({path: paper + '.pdf', printBackground:true, width:'1024px', height:'768px', margin: {top:"0px", right:"0px", bottom:"0px", left:"0px"} });
resolve();
});
})
и он несет единоличную ответственность, только создание PDF.
3 - тогда я управлял обещаниями page.goto
и PDF с Promise.all
await Promise.all([
page.goto(url, {"waitUntil":["load", "networkidle2"]}),
new Promise(async function(resolve, reject){
// ... pdf creation as above
})
]);
4 - я переместил page.close
после Promise.all
await Promise.all([
// page.goto
// PDF creation
]);
await page.close();
resolve();
И теперь все работает, вот полный рабочий скрипт
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(async 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});
await Promise.all([
page.goto(url, {"waitUntil":["load", "networkidle2"]}),
new Promise(async function(resolve, reject){
//screenshot on first console message
page.once("console", async () => {
await page.pdf({path: paper + '.pdf', printBackground:true, width:'1024px', height:'768px', margin: {top:"0px", right:"0px", bottom:"0px", left:"0px"} });
resolve();
});
})
]);
await page.close();
resolve();
})
}
//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);
}
}
await browser.close();
}
await stepThru();
});
Пожалуйстаобратите внимание, что: - я изменил networkidle0
на networkidle2
, потому что веб-сайту nytimes.com требуется очень много времени, чтобы получить состояние 0 сетевых запросов (из-за AD и т. д.).Вы можете ждать networkidle0
, очевидно, но это зависит от вас, это выходит за рамки вашего вопроса (в этом случае увеличьте время ожидания page.goto
) - сайт www.washingtonpost.com
переходит на ошибку TOO_MANY_REDIRECTS
, поэтому я изменился на washingtonpost.com
но я думаю, что вам стоит больше об этом поговорить.Для тестирования скрипта я использовал больше раз сайт nytimes
и другие сайты.Опять же: это выходит за рамки вашего вопроса
Дайте мне знать, если вам нужна дополнительная помощь ?