Puppeteer 是为运行e2e
测试而设计的。它可以用于网页抓取和其他事情,但这是它的意图。如果您考虑如何使用 chrome,您不可能完全并行下载 3 个文件。您需要打开 1 个选项卡,按“下载”,然后转到下一个选项卡按“下载”,依此类推。
即使切换到新选项卡,下载本身也会继续。
所以在脚本中你必须做同样的事情。一个接一个地开始下载,但在开始后,下载本身是在后台完成的。
例如:
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();
如果您想完全并行执行,则需要启动多个puppeteer
实例,如下所示:
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();