2014-11-24 3 views
8

Ich benutze Nightmare, um einen automatisierten Downloader für die heutige Zeitung zu erstellen. Ich habe es geschafft, mich anzumelden und auf die angegebene Seite zu gehen. Allerdings konnte ich nicht herausfinden, wie man eine Datei mit Nightmare herunterlädt.Laden Sie eine Datei mit Nightmare herunter

var Nightmare = require('nightmare'); 
new Nightmare() 
    .goto('https://login.nrc.nl/login?service=http://digitaleeditie.nrc.nl/welkom') 
    .type('input[name="username"]', 'Username') 
    .type('input[name="password"]','Password') 
    .click('button[type="submit"]') 
    .wait() 
    .goto('http://digitaleeditie.nrc.nl/digitaleeditie/NH/2014/10/20141124___/downloads.html') 
    .wait() 
    .click('a[href="/digitaleeditie/helekrant/epub/nrc_20141124.epub"]') 
    .wait() 

    .url(function(url) { 
     console.log(url) 
    }) 
    .run(function (err, nightmare) { 
     if (err) return console.log(err); 
     console.log('Done!'); 
    }); 

Ich habe versucht, die Datei herunterzuladen, indem Sie auf den Download-Button klicken. Dies scheint jedoch nicht zu funktionieren.

Antwort

4

PhantomJS (und CasperJS und Nightmare) lösen keinen Download (Dialog) aus, wenn Sie auf etwas klicken, das heruntergeladen werden soll. Also, es ist notwendig, es selbst herunterzuladen. Wenn Sie die URL der Datei herausfinden können, kann sie einfach mithilfe eines XMLHttpRequest aus dem Seitenkontext heruntergeladen werden.

So müssen Sie

.click('a[href="/digitaleeditie/helekrant/epub/nrc_20141124.epub"]') 

für

.evaluate(function ev(){ 
    var el = document.querySelector("[href*='nrc_20141124.epub']"); 
    var xhr = new XMLHttpRequest(); 
    xhr.open("GET", el.href, false); 
    xhr.overrideMimeType("text/plain; charset=x-user-defined"); 
    xhr.send(); 
    return xhr.responseText; 
}, function cb(data){ 
    var fs = require("fs"); 
    fs.writeFileSync("book.epub", data, "binary"); 
}) 

Sie auch die neuere Art und Weise anzufordern binäre Daten verwenden, um austauschen kann.

.evaluate(function ev(){ 
    var el = document.querySelector("[href*='.pdf']"); 
    var xhr = new XMLHttpRequest(); 
    xhr.open("GET", el.href, false); 
    xhr.responseType = "arraybuffer"; 
    xhr.send(); 

    var bytes = []; 
    var array = new Uint8Array(xhr.response); 
    for (var i = 0; i < array.length; i++) { 
     bytes[i] = array[i]; 
    } 
    return bytes; 
}, function cb(data){ 
    var fs = require("fs"); 
    fs.writeFileSync("book.epub", new Buffer(data), "binary"); 
}) 

Beide Möglichkeiten sind beschrieben on MDN. Here ist ein Beispielskript, das einen Proof of Concept zeigt.

+0

Ich habe versucht, dies zu implementieren. Allerdings nur eine 4k-Datei mit dem gleichen Namen herunterladen. Es wird nicht die gesamte Datei heruntergeladen. –

+0

4k ist ein bisschen willkürlich. Was ist der Inhalt? Vielleicht ist das eine Fehlerseite. –

+0

Es ist eine EPUB-Datei der Größe 4k. Wenn es in einem Texteditor geöffnet wird, enthält es nur null. –

1

Ich habe meine Downloads super einfach mit der request module, wie beschrieben here.

var Nightmare = require('nightmare'); 
var fs = require('fs'); 
var request = require('request'); 

new Nightmare() 
    .goto('https://login.nrc.nl/login?service=http://digitaleeditie.nrc.nl/welkom') 
    .insert('input[name="username"]', 'Username') 
    .insert('input[name="password"]','Password') 
    .click('button[type="submit"]') 
    .wait() 
    .goto('http://digitaleeditie.nrc.nl/digitaleeditie/NH/2014/10/20141124___/downloads.html') 
    .wait() 
    .then(function() { 
    download('http://digitaleeditie.nrc.nl/digitaleeditie/helekrant/epub/nrc_20141124.epub', 'myBook.epub', function() { 
     console.log('done'); 
    }); 
    }) 
    .catch(function (err) { 
    console.log(err); 
    }) 

function download(uri, filename, callback) { 
    request.head(uri, function() { 
    request(uri).pipe(fs.createWriteStream(filename)).on('close', callback); 
    }); 
} 

Run npm i request um request zu verwenden.

+0

Fehler im Code - fehlende ',' zwischen den Argumenten beim Aufruf von download() –

2

Es gibt eine Nightmare download plugin. Sie können die Datei herunterladen, nur mit diesem Code unter:

var Nightmare = require('nightmare'); 
 
require('nightmare-download-manager')(Nightmare); 
 
var nightmare = Nightmare(); 
 
nightmare.on('download', function(state, downloadItem){ 
 
    if(state == 'started'){ 
 
    nightmare.emit('download', '/some/path/file.zip', downloadItem); 
 
    } 
 
}); 
 

 
nightmare 
 
    .downloadManager() 
 
    .goto('https://github.com/segmentio/nightmare') 
 
    .click('a[href="/segmentio/nightmare/archive/master.zip"]') 
 
    .waitDownloadsComplete() 
 
    .then(() => { 
 
    console.log('done'); 
 
    });

0

Albtraum wird es richtig herunterladen, wenn Sie auf den Download-Link klicken.

const Nightmare   = require('nightmare'); 
const show    = (process.argv[2].includes("true")) ? true : false; 
const nightmare   = Nightmare({ show: show }); 

nightmare 
    .goto("https://github.com/segmentio/nightmare") 
    .click('a[href="/segmentio/nightmare/archive/master.zip"]') 
    .end(() => "Done!") 
    .then((value) => console.log(value));