node.js - 如何使用 Puppeteer 等待所有下载完成?

标签 node.js puppeteer

我有一个小型网络抓取应用程序,它从网络应用程序下载多个文件,其中的 URL 需要访问该页面。

如果我在运行之间保持浏览器实例处于事件状态,则效果很好,但我想在运行之间关闭该实例。当我调用 browser.close() 时,我的下载会停止,因为 chrome 实例在下载完成之前已关闭。

puppeteer 是否提供了一种方法来检查下载是否仍然有效,并等待它们完成?我尝试过 page.waitForNavigation({ waitUntil: "networkidle0"})"networkidle2",但这些似乎无限期地等待。

<小时/>
  • node.js 8.10
  • puppeteer 师1.10.0

最佳答案

更新:

现在是 2022 年。使用 Playwright 来摆脱这个困境。 manage downloads

它还有“更智能”的定位器,每次在 click() 之前都会检查选择器

<小时/>

puppeteer 师的旧版本:

我的解决方案是使用chrome自带的chrome://downloads/页面来管理下载文件。这个解决方案可以很容易地使用chrome自己的功能自动重新启动失败的下载

此示例当前为“单线程”,因为它仅监视下载管理器页面中出现的第一个项目。但是您可以通过迭代该页面中的所有下载项目 (#frb0~#frbn) 轻松地将其适应“无限线程”,好吧,请照顾好您的网络: )

dmPage = await browser.newPage()
await dmPage.goto('chrome://downloads/')

await your_download_button.click() // start download

await dmPage.bringToFront() // this is necessary
await dmPage.waitForFunction(
    () => {
        // monitoring the state of the first download item
        // if finish than return true; if fail click
        const dm = document.querySelector('downloads-manager').shadowRoot
        const firstItem = dm.querySelector('#frb0')
        if (firstItem) {
            const thatArea = firstItem.shadowRoot.querySelector('.controls')
            const atag = thatArea.querySelector('a')
            if (atag && atag.textContent === '在文件夹中显示') { // may be 'show in file explorer...'? you can try some ids, classess and do a better job than me lol
                return true
            }
            const btn = thatArea.querySelector('cr-button')
            if (btn && btn.textContent === '重试') { // may be 'try again'
                btn.click()
            }
        }
    },
    { polling: 'raf', timeout: 0 }, // polling? yes. there is a 'polling: "mutation"' which kind of async
)
console.log('finish')

关于node.js - 如何使用 Puppeteer 等待所有下载完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53471235/

相关文章:

javascript - 如何获取伪元素的计算值?

从浏览器进行 Node.js 和 Mocha 测试

javascript - 环回中的写保护属性

node.js - NPM 无法在 Windows 上安装 "truffle"

javascript - 为什么我的 for 循环只返回 1 个值

javascript - 在 Puppeteer 中访问 javascript 变量

javascript - Puppeteer - 使用 querySelectorAll() 访问动态 HTML 环境中的元素

node.js - Docker Node :Alpine-12: how to install Chromium 73 in Dockerfile?

node.js - 如何使用 puppeteer 从打印预览下载 pdf

javascript - 声明 Node.js 项目 : Is there only one "server file" in node. js?