Как я могу последовательно загружать несколько файлов с помощью NighmareJs?

Я очень новичок в 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');
  });

person stepse    schedule 07.01.2017    source источник


Ответы (1)


Отвечая на мой собственный вопрос. Прочитав это, это и это несколько раз, я понял, как комбинировать селекторы и промисы для цикла click().download(). Суть в том, чтобы дать каждой ссылке для скачивания в Assessment() свой уникальный идентификатор, а затем вернуть массив идентификаторов. После этого .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()
  });

Теперь, если мне нужно распечатать информацию о каждой загрузке, вместо того, чтобы возвращать идентификаторы загруженных файлов, я добавляю .then после download(), чтобы вернуть информацию о завершенной загрузке. Этот фрагмент кода я взял из этого тестового скрипта , который в ретроспективе похож на сценарий, который я представляю в этом ответе! Итак, соответствующий код изменяется таким образом, от

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

to

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

person stepse    schedule 07.01.2017