2017-01-07 2 views
0

Я очень новичок в NodeJs и NightmareJs. Мне нужно загрузить несколько файлов с той же страницы, используя плагин nightmare-inline-download. Пока что мой код ниже может скачать первый файл. Но я не могу понять, как загрузить все файлы, связанные со страницей, то есть как правильно обходить click(selector).download(). Более того, как я буду уступать зацикленным загрузкам, чтобы получить все загруженные имена файлов?Как я могу загрузить несколько файлов с помощью NighmareJs?

Обратите внимание на теги 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'); 
    }); 

ответ

2

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

Смежные вопросы