如何等待Puppeteer完成所有下载?

时间:2018-11-25 19:46:58

标签: node.js puppeteer

node.js 8.10 puppeteer 1.10.0

我有一个小型的Web抓取应用程序,可以从基于Java Server Faces的Web应用程序下载多个文件。通过单击每个文件的链接来触发下载。不幸的是,没有直接的下载网址,我必须这样做。

如果我在两次运行之间保持浏览器实例处于活动状态,则效果很好。出于稳定性原因,我想在两次运行之间关闭实例。 当我致电browser.close()时,我的下载已停止,因为chrome实例在下载完成之前已关闭。

木偶提供了一种检查下载是否仍处于活动状态并等待下载完成的方法吗?我已经尝试过page.waitForNavigation({ waitUntil: "networkidle0" })"networkidle2",但它们似乎会无限期地等待。

谢谢!

3 个答案:

答案 0 :(得分:1)

尝试进行await page.waitFor(50000);的时间与下载所需的时间相同。

或者看看watching for file changes on complete file transfer

答案 1 :(得分:1)

使用 puppeteer 和 chrome 我还有另一种可能对您有所帮助的解决方案。

如果您从 chrome 下载文件,它将始终具有“.crdownload”扩展名。当文件完全下载后,该扩展名将消失。

所以,我正在使用循环函数和它可以迭代的最大次数,如果当时没有下载文件..我将删除它。我一直在检查该扩展名的文件夹。

async checkFileDownloaded(path, timer) {
    return new Promise(async (resolve, reject) => {
        let noOfFile;
        try {
            noOfFile = await fs.readdirSync(path);
        } catch (err) {
            return resolve("null");
        }
        for (let i in noOfFile) {
            if (noOfFile[i].includes('.crdownload')) {
                await this.delay(20000);
                if (timer == 0) {
                    fs.unlink(path + '/' + noOfFile[i], (err) => {
                    });
                    return resolve("Success");
                } else {
                    timer = timer - 1;
                    await this.checkFileDownloaded(path, timer);
                }
            }
        }
        return resolve("Success");
    });
}

答案 2 :(得分:0)

如果您具有文件名或其他检查方法的建议,则为替代方法。

cpOld := c.comps[cpNew.id] = cpNew

实施:


async function waitFile (filename) {

    return new Promise(async (resolve, reject) => {
        if (!fs.existsSync(filename)) {
            await delay(3000);    
            await waitFile(filename);
            resolve();
        }else{
          resolve();
        }

    })   
}

function delay(time) {
    return new Promise(function(resolve) { 
        setTimeout(resolve, time)
    });
}