我对NodeJs和NightmareJs都很陌生。我需要使用nightmare-inline-download插件从同一页面下载多个文件。
到目前为止,我的代码可以下载第一个文件。但我无法弄清楚如何下载链接到该页面的所有文件,即如何以正确的方式循环click(selector).download()
。此外,我将如何在循环下载中获得所有下载的文件名?
请注意我需要点击的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');
});
答案 0 :(得分:2)
回答我自己的问题。看完之后
this,
this
和this
几次,
我想到如何组合选择器和promises循环click()。download()。
关键是给evaluate()中的每个下载链接自己唯一的id,然后返回一个id数组。之后.then
可以将数组减少到承诺列表,每个承诺都会点击
并下载由唯一ID选择的元素。最终.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()
});
现在,如果我需要打印有关每次下载的信息,而不是返回下载的文件ID,我会在.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
});