Quiero descargar varios archivos abriendo varias pestañas por bucle y descargando el archivo de cada pestaña por separado, pero solo está descargando un archivo de la última pestaña en una ruta de descarga diferente.
Aquí hay un código de muestra que no puede descargar varios archivos en una ruta de descarga separada por un titiritero.
const puppeteer = require('puppeteer'); const path = require('path'); async function download(i, browser) { const page = await browser.newPage(); await page.goto('https://vinay-jtc.github.io/test-pdf', { waitUntil: 'networkidle2', }); const billsData = await page.$$('.pdf'); const downloadPath = path.resolve(`/home/vanni/download/${i}`); await page._client.send('Page.setDownloadBehavior', { behavior: 'allow', downloadPath: downloadPath, }); await billsData[i].click(); await new Promise((resolve) => setTimeout(resolve, 5000)); } async function simplefileDownload() { const browser = await puppeteer.launch({ headless: false }); const promises = []; for (let i = 0; i < 4; i++) { promises.push(download(i, browser)); } await Promise.all(promises).then(() => { browser.close(); }); } simplefileDownload();alguien puede ayudar con este problema?
Titiritero está hecho para ejecutar pruebas e2e . Se puede usar para webscraping y otras cosas, pero esa era su intención. Si piensas en cómo usas Chrome, no es posible que descargues 3 archivos completamente en paralelo. Debe abrir 1 pestaña, presionar "descargar" y luego ir a la siguiente pestaña para presionar "descargar" y así sucesivamente.
La descarga en sí continúa incluso cuando se cambia a una nueva pestaña.
Así que en el guión tienes que hacer lo mismo. Inicie las descargas una tras otra, pero después del inicio, la descarga en sí se realiza en segundo plano.
Por ejemplo:
const puppeteer = require('puppeteer'); const path = require('path'); async function startDownload(i, browser) { const page = await browser.newPage(); await page.goto('https://vinay-jtc.github.io/test-pdf', { waitUntil: 'networkidle2', }); const billsData = await page.$$('.pdf'); const downloadPath = path.resolve(`/home/vanni/download/${i}`); await page._client.send('Page.setDownloadBehavior', { behavior: 'allow', downloadPath: downloadPath, }); await billsData[i].click(); } // ideally you would watch the filesystem for being able to return at the moment // the file was donwloaded. You can achieve that using the `chokidar` module for example. async function waitForDownload(ms) { await new Promise((resolve) => setTimeout(resolve, ms)); } async function simplefileDownload() { const browser = await puppeteer.launch({ headless: false }); const promises = []; for (let i = 0; i < 4; i++) { // start the download, await it.. await startDownload(i, browser) // After it has started, you can proceed!. promises.push(waitForDownload(5 * 1000)); } await Promise.all(promises).then(() => { browser.close(); }); } simplefileDownload(); Si desea hacerlo completamente en paralelo, debe iniciar varias instancias de puppeteer de la siguiente manera:
const puppeteer = require('puppeteer'); const path = require('path'); async function startDownload(i) { // run new puppeteer instance on each download. const browser = await puppeteer.launch({ headless: false }); const page = await browser.newPage(); await page.goto('https://vinay-jtc.github.io/test-pdf', { waitUntil: 'networkidle2', }); const billsData = await page.$$('.pdf'); const downloadPath = path.resolve(`/home/vanni/download/${i}`); await page._client.send('Page.setDownloadBehavior', { behavior: 'allow', downloadPath: downloadPath, }); await billsData[i].click(); await waitForDownload(5 * 1000) await browser.close(); } // ideally you would watch the filesystem for being able to return at the moment // the file was donwloaded. You can achieve that using the `chokidar` module for example. async function waitForDownload(ms) { await new Promise((resolve) => setTimeout(resolve, ms)); } async function simplefileDownload() { const promises = []; for (let i = 0; i < 4; i++) { // do it like you did before. promises.push(startDownload(i)); } await Promise.all(promises).then(() => { console.log('done.') }); } simplefileDownload();