如何使用无头使用 puppeteer 下载文件:真的?

新手上路,请多包涵

我一直在运行以下代码,以便从网站下载 csv 文件 http://niftyindices.com/resources/holiday-calendar

 const puppeteer = require('puppeteer');

(async () => {
const browser = await puppeteer.launch({headless: true});
const page = await browser.newPage();

await page.goto('http://niftyindices.com/resources/holiday-calendar');
await page._client.send('Page.setDownloadBehavior', {behavior: 'allow',
downloadPath: '/tmp'})
await page.click('#exportholidaycalender');
await page.waitFor(5000);
await browser.close();
})();

使用 headless: false 它可以工作,它将文件下载到 /Users/user/Downloads 。与 headless: true 它不起作用。

I’m running this on a macOS Sierra (MacBook Pro) using puppeteer version 1.1.1 which pulls Chromium 66.0.3347.0 into .local-chromium/ directory and used npm initnpm i --save puppeteer 进行设置。

知道有什么问题吗?

提前感谢您的时间和帮助,

原文由 Antonio Gomez Alvarado 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.6k
2 个回答

此页面通过创建逗号分隔的字符串并通过设置数据类型来强制浏览器下载它来下载 csv

 let uri = "data:text/csv;charset=utf-8," + encodeURIComponent(content);
window.open(uri, "Some CSV");

这在 chrome 上会打开一个新选项卡。

您可以点击此事件并将内容实际下载到文件中。不确定这是否是最好的方法,但效果很好。

 const browser = await puppeteer.launch({
  headless: true
});
browser.on('targetcreated', async (target) => {
    let s = target.url();
    //the test opens an about:blank to start - ignore this
    if (s == 'about:blank') {
        return;
    }
    //unencode the characters after removing the content type
    s = s.replace("data:text/csv;charset=utf-8,", "");
    //clean up string by unencoding the %xx
    ...
    fs.writeFile("/tmp/download.csv", s, function(err) {
        if(err) {
            console.log(err);
            return;
        }
        console.log("The file was saved!");
    });
});

const page = await browser.newPage();
.. open link ...
.. click on download link ..

原文由 Sumit Mishra 发布,翻译遵循 CC BY-SA 3.0 许可协议

昨天我花了几个小时仔细研究 这个线程 和 Stack Overflow,试图弄清楚如何通过在经过身份验证的会话中以无头模式单击下载链接来让 Puppeteer 下载 csv 文件。这里接受的答案在我的情况下不起作用,因为下载不会触发 targetcreated ,下一个答案,无论出于何种原因,都没有保留经过身份验证的会话。 这篇文章 挽救了这一天。简而言之, fetch 。希望这可以帮助其他人。

 const res = await this.page.evaluate(() =>
{
    return fetch('https://example.com/path/to/file.csv', {
        method: 'GET',
        credentials: 'include'
    }).then(r => r.text());
});

原文由 Justin 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题