2017-01-07 2 views
0

Ich bin neu bei NodeJs und NightmareJs. Ich muss mehrere Dateien von der gleichen Seite mit dem nightmare-inline-download Plugin herunterladen. Bis jetzt kann mein Code unten die erste Datei herunterladen. Aber ich kann nicht herausfinden, wie man alle mit der Seite verbundenen Dateien herunterlädt, das heißt, wie man click(selector).download() in der richtigen Weise umschlingt. Außerdem, wie werde ich bei den geloopten Downloads nachgeben, um alle heruntergeladenen Dateinamen zu erhalten?Wie kann ich mehrere Dateien mit NighmareJs seriell herunterladen?

Beachten Sie die HTML <a> Tags, die ich klicken muss: <a target="_blank" class="download-link">Download</a>. Es gibt kein href Attribut; Durch Klicken auf das Tag wird ein Skript ausgelöst, das den Download startet.

Die Website erlaubt nur einen Download zu der Zeit zu starten.

Hier ist mein Code so weit:

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

Antwort

2

meine eigene Frage zu beantworten. Nach Lesen this, this und this mehrmals, ich dachte, wie Selektoren und verspricht Schleife über Klick zu kombinieren(). Download(). Der Schlüssel besteht darin, jedem Download-Link in evaluate() seine eigene eindeutige ID zu geben und dann ein Array der IDs zurückzugeben. Danach kann .then das Array auf eine Liste von Versprechen reduzieren, wobei jedes Versprechen auf klickt und das durch eindeutige ID ausgewählte Element herunterlädt. Ein endgültiges .then startet die Downloads. Der Code wird:

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

Nun, wenn ich Informationen über die einzelnen Download drucken müssen, anstatt die heruntergeladene Datei-IDs zurückkehrte, ich .then nach download() fügen Sie die Informationen über den Download abgeschlossen zurückzukehren. Dieses Stückchen Code habe ich aus dieser test script entnommen, die im Rückblick ähnlich dem Skript ist, das ich in dieser Antwort präsentiere! So , ändert sich der entsprechende Code auf diese Weise, von

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

zu

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

Verwandte Themen