如何使用NighmareJs连续下载多个文件?

时间:2017-01-07 14:14:59

标签: javascript node.js nightmare

我对NodeJs和NightmareJs都很陌生。我需要使用nightmare-inline-download插件从同一页面下载多个文件。 到目前为止,我的代码可以下载第一个文件。但我无法弄清楚如何下载链接到该页面的所有文件,即如何以正确的方式循环click(selector).download()。此外,我将如何在循环下载中获得所有下载的文件名?

请注意我需要点击的HTML <a>代码:<a target="_blank" class="download-link">Download</a>。没有href属性;单击标记会触发启动下载的脚本。

该网站目前只允许下载一次。

到目前为止,这是我的代码:

var Nightmare = require('nightmare');
require('nightmare-inline-download')(Nightmare);
var nightmare = Nightmare({ show: false });
nightmare
  .goto(pageUrl)
  .evaluate({
    var links = document.querySelectorAll('.download-link');
    for(var i = 0, i < links.length; i++) {
      links[i].setAttribute('download-this', 'true');
    }
  })
  .click('[download-this="true"]') // will select just the first element
  .download()
  .end()
  .then(() => {
    console.log('done');
  });

1 个答案:

答案 0 :(得分:2)

回答我自己的问题。看完之后 thisthisthis 几次, 我想到如何组合选择器和promises循环click()。download()。 关键是给evaluate()中的每个下载链接自己唯一的id,然后返回一个id数组。之后.then 可以将数组减少到承诺列表,每个承诺都会点击 并下载由唯一ID选择的元素。最终.then开始下载。代码变为:

var Nightmare = require('nightmare');
require('nightmare-inline-download')(Nightmare);
var nightmare = Nightmare({ show: false });
nightmare
  .goto(pageUrl)
  .evaluate({
    var links = document.querySelectorAll('.download-link');
    var ids = [];
    for(var i = 0, i < links.length; i++) {
      links[i].setAttribute('download-this', i);
      ids.push(i);
    }
    return ids
  })
  .then(function (ids) {
    return ids.reduce(function (accumulator, id) {
      return accumulator.then(function (results) {
        nightmare
          .click('[download-this=["' + id + '"]')
          .download();
        results.push(id);
        return results; // ids of downloaded files
      })
    }, Promise.resolve([]))
  })
  .then(function (results) {
    console.log('results', results);
    return nightmare.end()
  })
  .catch(function (error) {
    console.error('Error:', error);
    return nightmare.end()
  });

现在,如果我需要打印有关每次下载的信息,而不是返回下载的文件ID,我会在.then之后添加download()以返回有关已完成下载的信息。我从这个test script获取的这段代码,回想起来就像我在这个答案中提到的脚本类似! 因此,相关代码以这种方式改变,来自

    nightmare
      .click('[download-this=["' + id + '"]')
      .download();
    results.push(id);
    return results; // ids of downloaded files

    return nightmare
      .click('[download-this=["' + id + '"]')
      .download()
      .then(info => {
        results.push(info);
        return results; // info about downloaded files
      });