如何在nightmare.js中运行多个评估方法?

mic*_*ger 3 javascript nightmare electron

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

在对噩梦实例进行身份验证后,我遍历多个页面(需要登录),然后调用执行所有页面加载的run方法.

从每个页面我想获取特定的内容,所以我调用evaluate函数,确保我们在浏览器范围内执行.从evaluate函数返回的任何内容都将成为run方法中的参数

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

任何人都可以建议如何在一个噩梦实例上运行多个评估方法并从每个方法中提取信息?

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);
  }
}); )
Run Code Online (Sandbox Code Playgroud)

jus*_*ase 9

我对噩梦并不是特别了解,但似乎你可能只是因为异步而遇到问题,这在js中是个难题.

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

要实现的关键是,当您使用*函数名称之前,该函数将成为生成器函数,允许您使用yield关键字.只要你yield的代码行在转到下一行代码之前等待返回的promise完成,它就会返回那个产生的值.您可以使用vo库将生成器函数转换为回调函数,该函数返回所有生成结果的数组.

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()
}
Run Code Online (Sandbox Code Playgroud)