Javascript 如何让多个求值方法在噩梦中运行?

Javascript 如何让多个求值方法在噩梦中运行?,javascript,electron,nightmare,Javascript,Electron,Nightmare,我正在使用梦魇.js来抓取网页内容 在验证了噩梦实例之后,我循环了多个页面(需要登录),然后调用执行所有页面加载的run方法 我希望从每个页面获取特定的内容,因此我调用evaluate函数,以确保我们在浏览器范围内执行。从evaluate函数返回的内容将成为run方法中的参数 但是我尝试多次运行evaluate函数(每个页面一次)。但是evaluate函数只能向run方法返回一次输出。我尝试将内容推送到全局变量(在主范围内),但无法从浏览器范围内访问它 有人能建议如何在一个噩梦实例上运行多个ev

我正在使用梦魇.js来抓取网页内容

在验证了噩梦实例之后,我循环了多个页面(需要登录),然后调用执行所有页面加载的run方法

我希望从每个页面获取特定的内容,因此我调用evaluate函数,以确保我们在浏览器范围内执行。从evaluate函数返回的内容将成为run方法中的参数

但是我尝试多次运行evaluate函数(每个页面一次)。但是evaluate函数只能向run方法返回一次输出。我尝试将内容推送到全局变量(在主范围内),但无法从浏览器范围内访问它

有人能建议如何在一个噩梦实例上运行多个evaluate方法并从每个实例中提取信息吗

var Nightmare = require("nightmare");

//Creates the authenticated nightmare instance

var scraper = new Nightmare()
  .goto('https://www.example.com/signin')
  .type('#login', 'username')
  .type('#password', 'password')
  .click('#btn')
  .run(function(err, nightmare) {
    if (err) {
      console.log(err);
    }
    console.log('Done.');
  });

for (var i = 0; i < 4; i++) {
  scraper
    .goto('https://www.example.com/page'+i)
    .wait(1000)
    .evaluate(function(){
      return $('#result > h3').text()
    })
}

scraper.run(function(err, result) {
  console.log(result)
  if (err) {
    console.log(err);
  }
}); )
var噩梦=需要(“噩梦”);
//创建经过身份验证的噩梦实例
var scraper=新噩梦()
后藤先生('https://www.example.com/signin')
.type(“#登录”、“用户名”)
.type(“#密码”、“密码”)
。单击(“#btn”)
.run(函数(错误、噩梦){
如果(错误){
控制台日志(err);
}
console.log('Done');
});
对于(变量i=0;i<4;i++){
刮刀
后藤先生('https://www.example.com/page"(i)
.等等(1000)
.评估(功能){
返回$('#result>h3')。text()
})
}
scraper.run(函数(错误、结果){
console.log(结果)
如果(错误){
控制台日志(err);
}
}); )

我对噩梦的了解不多,但似乎您可能在异步方面有问题,这在js中通常是个难题

好消息是,您可以重新构造代码,并依靠生成器使其相当简单地工作

要实现的关键是,当您在函数名之前使用
*
时,该函数将成为生成器函数,这允许您使用
yield
关键字。每当您
yield
时,该行代码将等待返回的承诺完成,然后再转到下一行代码,结果它将返回生成的值。可以使用该库将生成器函数转换为回调函数,回调函数返回所有生成结果的数组

var Nightmare = require('../nightmare')
var vo = require('vo')

vo(run)(function(err, result) {
  if (err) throw err
  console.log('#result > h3: ', result)
})

function *run() {
  var nightmare = Nightmare();
  yield nightmare
    .goto('https://www.example.com/signin')
    .type('#login', 'username')
    .type('#password', 'password')
    .click('#btn')

  for (var i = 0; i < 4; i++) {
    yield nightmare
      .goto('https://www.example.com/page'+i)
      .wait(1000)
      .evaluate(function(){
        return $('#result > h3').text()
      })
  }

  yield nightmare.end()
}
var梦魇=require(“../monamine”)
var vo=require('vo')
vo(运行)(功能(错误、结果){
如果(错误)抛出错误
console.log(“#result>h3:”,result)
})
函数*run(){
var噩梦=噩梦();
屈服噩梦
后藤先生('https://www.example.com/signin')
.type(“#登录”、“用户名”)
.type(“#密码”、“密码”)
。单击(“#btn”)
对于(变量i=0;i<4;i++){
屈服噩梦
后藤先生('https://www.example.com/page"(i)
.等等(1000)
.评估(功能){
返回$('#result>h3')。text()
})
}
结束
}

这与电子有什么关系?(它有电子标签)@justin.m.chase噩梦.js最近从PhantomJS切换到了electron。OP想说他使用了一个更新的版本。我想说的是,版本信息必须在问题正文中提供。@ArtjomB。我明白了,很有趣。实际上我只是在考虑做一个这样的电子跑步机,我现在可能会用它来代替。我只是在努力解决同样的问题,这就是我要走的路。然而,我看到了两个问题。1) 可能是打字错误,但未定义
结果
。2) 另一方面,
result
将只包含上一个
.evaluate()
的结果,而不是所有结果的列表。vo一个接一个地链接产生的承诺(管道),因此只有最后实现的承诺的结果在那里可用。(vo版本4.0.2,可能从那时起vo的语义发生了变化)谢谢@Insa。我更新了代码以反映您的评论。