I am using puppeteer to login into my account of a content provider I work with and download a lot of zips. I can easily get the array with all the links I need to download then I loop through the array and use browser.downloads.download (code taken from MDN) to download each link. The problem is that even before it starts to download it tells me:
error: TypeError: Cannot read property 'download' of undefined
Here is my code:
const puppeteer = require('puppeteer'); require('dotenv').config(); (async () => { const browser = await puppeteer.launch({ headless: false, args: ['--start-maximized'], defaultViewport: null, }); const page = await browser.newPage(); try { await page.goto(process.env.GROB_URL); page.setDefaultNavigationTimeout(0); await page.waitForSelector('input[name=user]', { visible: true, }); //login await page.type('input[name=user]', process.env.GROB_USER); await page.type('input[name=pass]', process.env.GROB_PASS); await page.click('input#head-login'); await page.waitForSelector('.light-highlight-row'); const setValue = new Set(); // get the nodelist array with all the download links let arr = await page.$$('.light-highlight-row td:nth-child(8) a'); for (let item of arr) { const jsonValue = await item.getProperty('href'); const value = await jsonValue.jsonValue(); setValue.add(value); } const finalArray = Array.from(setValue); //all good till here function onStartedDownload(id) { console.log(`Started downloading: ${id}`); } function onFailed(error) { console.log(`Download failed: ${error}`); } //donwload all of them finalArray.forEach((link) => { var downloadUrl = link; var downloading = browser.downloads.download({ url: downloadUrl, }); downloading.then(onStartedDownload(link), onFailed(link)); }); page.waitForTimeout(500_000); } catch (error) { console.log('error: ', error); } })();
It somehow tells me the browser is undefined, but it is JS API.
Advertisement
Answer
There is no this method or property downloads in Browse object, you can check it here on puppeteer docs.
you can try using a http request to get your files, for example using this strategy below, I couldn’t try it, but I hope it is usefull for you =)
const puppeteer = require('puppeteer'); require('dotenv').config(); async function downloadFile(downloadUrl) { await fetch(downloadUrl) .then(res => res.blob()) .then(blob => { var file = window.URL.createObjectURL(blob); window.location.assign(file); }); } (async () => { const browser = await puppeteer.launch({ headless: false, args: ['--start-maximized'], defaultViewport: null, }); const page = await browser.newPage(); try { await page.goto(process.env.GROB_URL); page.setDefaultNavigationTimeout(0); await page.waitForSelector('input[name=user]', { visible: true, }); //login await page.type('input[name=user]', process.env.GROB_USER); await page.type('input[name=pass]', process.env.GROB_PASS); await page.click('input#head-login'); await page.waitForSelector('.light-highlight-row'); const setValue = new Set(); // get the nodelist array with all the download links let arr = await page.$$('.light-highlight-row td:nth-child(8) a'); for (let item of arr) { const jsonValue = await item.getProperty('href'); const value = await jsonValue.jsonValue(); setValue.add(value); } const finalArray = Array.from(setValue); //all good till here function onStartedDownload(id) { console.log(`Started downloading: ${id}`); } function onFailed(error) { console.log(`Download failed: ${error}`); } //donwload all of them finalArray.forEach((link) => { //here you can call the download funcion passing link and a filename await downloadFile(link) }); page.waitForTimeout(500_000); } catch (error) { console.log('error: ', error); } })()