Estoy trabajando en la creación de PDF desde la página web.
La aplicación en la que estoy trabajando es una aplicación de una sola página.
Probé muchas opciones y sugerencias en https://github.com/GoogleChrome/puppeteer/issues/1412
Pero no está funcionando
const browser = await puppeteer.launch({ executablePath: 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe', ignoreHTTPSErrors: true, headless: true, devtools: false, args: ['--no-sandbox', '--disable-setuid-sandbox'] }); const page = await browser.newPage(); await page.goto(fullUrl, { waitUntil: 'networkidle2' }); await page.type('#username', 'scott'); await page.type('#password', 'tiger'); await page.click('#Login_Button'); await page.waitFor(2000); await page.pdf({ path: outputFileName, displayHeaderFooter: true, headerTemplate: '', footerTemplate: '', printBackground: true, format: 'A4' });Lo que quiero es generar un informe en PDF tan pronto como la página se cargue por completo.
No quiero escribir ningún tipo de retraso, es decir, await page.waitFor(2000);
No puedo hacer waitForSelector porque la página tiene tablas y gráficos que se representan después de los cálculos.
La ayuda será apreciada.
Puede usar page.waitForNavigation() para esperar a que la nueva página se cargue por completo antes de generar un PDF:
await page.goto(fullUrl, { waitUntil: 'networkidle0', }); await page.type('#username', 'scott'); await page.type('#password', 'tiger'); await page.click('#Login_Button'); await page.waitForNavigation({ waitUntil: 'networkidle0', }); await page.pdf({ path: outputFileName, displayHeaderFooter: true, headerTemplate: '', footerTemplate: '', printBackground: true, format: 'A4', }); Si hay un determinado elemento que se genera dinámicamente y que le gustaría incluir en su PDF, considere usar page.waitForSelector() para asegurarse de que el contenido sea visible:
await page.waitForSelector('#example', { visible: true, });A veces, los eventos networkidle no siempre dan una indicación de que la página se ha cargado por completo. Todavía podría haber algunos scripts JS que modifiquen el contenido de la página. Por lo tanto, observar la finalización de las modificaciones del código fuente HTML por parte del navegador parece estar dando mejores resultados. Aquí hay una función que podría usar:
const waitTillHTMLRendered = async (page, timeout = 30000) => { const checkDurationMsecs = 1000; const maxChecks = timeout / checkDurationMsecs; let lastHTMLSize = 0; let checkCounts = 1; let countStableSizeIterations = 0; const minStableSizeIterations = 3; while(checkCounts++ <= maxChecks){ let html = await page.content(); let currentHTMLSize = html.length; let bodyHTMLSize = await page.evaluate(() => document.body.innerHTML.length); console.log('last: ', lastHTMLSize, ' <> curr: ', currentHTMLSize, " body html size: ", bodyHTMLSize); if(lastHTMLSize != 0 && currentHTMLSize == lastHTMLSize) countStableSizeIterations++; else countStableSizeIterations = 0; //reset the counter if(countStableSizeIterations >= minStableSizeIterations) { console.log("Page rendered fully.."); break; } lastHTMLSize = currentHTMLSize; await page.waitFor(checkDurationMsecs); } }; Puede usar esto después de la llamada de función de load / click de la página y antes de procesar el contenido de la página. p.ej
await page.goto(url, {'timeout': 10000, 'waitUntil':'load'}); await waitTillHTMLRendered(page) const data = await page.content()En algunos casos, la mejor solución para mí fue:
await page.goto(url, { waitUntil: 'domcontentloaded' });Algunas otras opciones que podrías probar son:
await page.goto(url, { waitUntil: 'load' }); await page.goto(url, { waitUntil: 'domcontentloaded' }); await page.goto(url, { waitUntil: 'networkidle0' }); await page.goto(url, { waitUntil: 'networkidle2' });Puede verificar esto en la documentación del titiritero: https://pptr.dev/?#?product=Puppeteer&version=v11.0.0&show=api-pagewaitfornavigationoptions