如何使用 Puppeteer 从 browser.downloads.download 修复 TypeError 'Cannot read property 'download' of undefined'

时间:2021-04-15 10:24:39

标签: javascript node.js browser typeerror puppeteer

我正在使用 puppeteer 登录我与我合作的内容提供商的帐户并下载了很多 zip。 我可以轻松获取包含需要下载的所有链接的数组,然后遍历数组并使用 browser.downloads.download(从 MDN 获取的代码)下载每个链接。问题是,它甚至在开始下载之前就告诉我:

error:  TypeError: Cannot read property 'download' of undefined

这是我的代码:

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);
  }
})();

它以某种方式告诉我浏览器未定义,但它是 JS API。

1 个答案:

答案 0 :(得分:1)

Browse 对象中没有此方法或属性下载,您可以在 puppeteer docs 上查看。

您可以尝试使用http请求来获取您的文件,例如使用下面的这个策略,我无法尝试,但我希望它对您有用=)

 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);
      }
    })()