2014-11-24 2 views
8

Я использую Nightmare для создания автоматизированного загрузчика для сегодняшней газеты. Мне удалось войти в систему и перейти на указанную страницу. Однако я не мог узнать, как загрузить файл с помощью Nightmare.Загрузить файл с помощью 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!'); 
    }); 

Я попытался загрузить файл, нажав кнопку загрузки. Однако это, похоже, не сработает.

ответ

4

PhantomJS (и CasperJS и Nightmare) не запускают загрузку (диалог) при нажатии на то, что должно быть загружено. Таким образом, его необходимо загрузить самостоятельно. Если вы можете узнать URL-адрес файла, его можно легко загрузить с помощью XMLHttpRequest из контекста страницы.

Так что вам нужно обменять

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

для

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

Вы также можете использовать новый способ запроса двоичных данных.

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

Оба способа описаны on MDN. Here - образец сценария, который показывает доказательство концепции.

+0

Я попытался реализовать это. Однако это только загружает файл 4k с тем же именем. Он не загружает весь файл. –

+0

4k немного произвольно. Что такое контент? Возможно, это страница с ошибкой. –

+0

Это файл epub размером 4k. Если он открыт в текстовом редакторе, он содержит только нуль. –

1

Я получил свои загрузки супер легко используя request module, как описано 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 для того, чтобы использовать request.

+0

ошибка в коде - отсутствует ',' между args при вызове download() –

2

Существует Nightmare download plugin. Вы можете скачать файл только с этим ниже код:

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

Кошмар загрузит его должным образом, если нажать на ссылку для загрузки.

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)); 
Смежные вопросы