1

我是 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
4

1 回答 1

3

其中的函数内容在.evaluate()浏览器上下文中运行。因此,fs不会data被提升到您定义的函数范围内。.evaluate() (您可以在此处阅读有关可变提升的更多信息。)

fs.write()不会按您的意愿工作 -fs.write()是异步的

另外,我怀疑$(selector).text()是否会产生您想要的结果-我认为这会将每个链接的链接文本连接在一起。我怀疑你想要他们在一个数组中?

此外,我应该指出,.run()不直接支持。这是一个内部函数,主要是为了兼容性而保留。

最后,您似乎正在使用自定义构建的 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);
})
于 2016-08-29T14:04:52.697 回答