我是JavaScript,node.js和NightmareJS的新手。
我在下面写了一个简单的脚本来从网页中提取一些文字,我想把它保存到文件中。
var nightmare = require('nightmare');
var data = [];
var fs = require('fs');
var usda = new nightmare()
.goto('yyyy')
.wait(20000)
.inject('js', 'jquery.js')
.evaluate(function(){
data = $x('//a').text();
fs.write("testOutput.json", JSON.stringify(data), 'w');
})
.end()
.run(function (err, nightmare) {
if (err) return console.log(err);
console.log('Done!');
});
我一直收到如下错误:
return binding.writeString(fd, buffer, offset, length, req);
^
TypeError: First argument must be file descriptor
答案 0 :(得分:3)
.evaluate()
内的函数内容在浏览器上下文中运行。因此,fs
和data
将不会被提升到您定义的功能范围内。 (您可以阅读有关变量提升的更多信息以及.evaluate()
here。)
fs.write()
无效 - fs.write()
is asynchronous。
另外,我怀疑$(selector).text()
会产生你想要的结果 - 我认为这会将每个链接的链接文本连接在一起。我怀疑你想要他们在一个数组?
此外,我应该指出.run()
isn't directly supported。这是一个内部功能,主要是为了保持兼容性。
最后,看起来您正在使用自定义构建的jQuery或第三方库来获得XPath支持。将来,包含这些信息会很有帮助。
所有这些都说,让我们修补你的例子让你开始。脱下袖口,这样的事情应该有效:
var nightmare = require('nightmare');
var fs = require('fs');
var usda = new nightmare()
.goto('yyyy')
.wait(20000)
.inject('js', 'jquery.js')
.evaluate(function(){
//using 'a', but this could be swapped for your xpath selector
return $('a').toArray().map((a) => $(a).text());
})
.end()
.then(function(anchors){
fs.writeFileSync('testOutput.json', JSON.stringify(anchors));
console.log('Done!');
});
.catch(function(err){
console.log(err);
})