2014-11-24 15 views
8

Używam Nightmare do tworzenia automatycznego downloadera do dzisiejszej gazety. Udało mi się zalogować i przejść do określonej strony. Jednak nie mogłem dowiedzieć się, jak pobrać plik z Nightmare.Pobierz plik za pomocą Nightmare

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

Próbowałem pobrać plik, klikając przycisk Pobierz. Jednak wydaje się, że to nie działa.

Odpowiedz

4

PhantomJS (i CasperJS and Nightmare) nie uruchamiają pobierania (okna dialogowego) po kliknięciu na coś, co powinno zostać pobrane. Tak więc konieczne jest pobranie go samemu. Jeśli możesz znaleźć adres URL pliku, możesz go łatwo pobrać za pomocą XMLHttpRequest z kontekstu strony.

Więc trzeba wymieniać

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

dla

.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"); 
}) 

Można również skorzystać z nowszego sposobu żądania danych binarnych.

.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"); 
}) 

Oba sposoby są opisane on MDN. Here to przykładowy skrypt, który pokazuje dowód koncepcji.

+0

Próbowałem to zaimplementować. Jednak to tylko pobrać plik 4k o tej samej nazwie. Nie pobiera całego pliku. –

+0

4k jest nieco arbitralny. Jaka jest zawartość? Może to jest strona błędu. –

+0

To jest plik epub o rozmiarze 4k. Jeśli jest otwarty w edytorze tekstu, zawiera tylko wartość null. –

1

Moje pliki do pobrania są bardzo łatwe przy użyciu request module, zgodnie z opisem 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 aby korzystać request.

+0

błąd w kodzie - brak "," między argumentami podczas wywoływania download() –

2

Istnieje Nightmare download plugin. Możesz pobrać plik tylko z tego kodu poniżej:

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

Nightmare będzie go pobrać prawidłowo, jeśli klikniesz na odnośnik pobierania.

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