2016-05-31 74 views
0

进行评估我正在尝试使用NightmareJS v2和Vo以及Node.JS来查​​看几个搜索项并从中收集数据。我的代码可以看到下面:NightmareJS无法使用vo

const nightmare = require('nightmare'), 
    vo = require('vo'), 
    nbot = nightmare({ title: 'Bot', 
         show: true }); 

const searchTerms = ['spacex', 'tesla', 'elon musk', 'hyperloop']; // EXAMPLE SEARCH TERMS 

vo(run)(function(err) { 
    if (err) throw err 
}); 

function * run() { 
    yield nbot.goto('http://google.com'); 

    yield * forEach(searchTerms, gen); 

    yield nbot.end() 
    .then(function(result) { 
    console.log(result) // STUFF SHOULD BE LOGGED HERE 
    }); 
} 

function * gen(item) { 
    yield nbot.wait('input[title="Search"]') 
      .click('input[title="Search"]') 
      .type('input[title="Search"]', item) 
      .click('input[name="btnK"]') 
      .wait(100) 
      .screenshot(item + '.png') 
      .insert('input[title="Search"]', '') 
      .evaluate(function() { 
       return 'foobar' // STUFF RETURNED HERE 
      }) 
} 

function * forEach (arr, fn) { // NEEDED BECAUSE FOREACH DOESN'T WORK IN GENERATORS 
    let i; 
    for (i = 0; i < arr.length; i++) { 
    yield * fn(arr[i]); 
    } 
} 

根据NightmareJS的文档,如果返回的evaluate里面的东西,然后它吐了出来,当您使用then。当我尝试这个时,我得到了未定义。我认为这是发电机的东西,但我是他们的新手,所以我不能说。帮助表示赞赏。

回答

2

这个例子是关闭,但它看起来像是混合和匹配生成器与Promise语法。 .evaluate()方法的行为与您所描述的相同,但当您使用vo(或co)时,.then()将由您负责管理,并将.then()的值返回到yield的左侧表达式,如果一个被定义。此外,对于它的价值,您的生成器不会返回值,因此您将(正确)得到undefined

This在迭代器,生成器,承诺和vo/co上进一步深入。您可能还想看看vo上的nightmare-examples文档。

最后,你的榜样,修改为从gen返回结果,通过forEach高达run

const nightmare = require('nightmare'), 
    vo = require('vo'), 
    nbot = nightmare({ 
    title: 'Bot', 
    show: true 
    }); 

const searchTerms = ['spacex', 'tesla', 'elon musk', 'hyperloop']; // EXAMPLE SEARCH TERMS 

vo(run)(function(err) { 
    if (err) throw err 
}); 

function* run() { 
    yield nbot.goto('http://google.com'); 

    var results = yield * forEach(searchTerms, gen); 
    console.log(results); 
    yield nbot.end(); 
} 

function* gen(item) { 
    var value = yield nbot.wait('input[title="Search"]') 
    .click('input[title="Search"]') 
    .type('input[title="Search"]', item) 
    .click('input[name="btnK"]') 
    .wait(100) 
    .screenshot(item + '.png') 
    .insert('input[title="Search"]', '') 
    .evaluate(function() { 
     return 'foobar' // STUFF RETURNED HERE 
    }); 

    return value; 
} 

function* forEach(arr, fn) { // NEEDED BECAUSE FOREACH DOESN'T WORK IN GENERATORS 
    let i; 
    var results = []; 
    for (i = 0; i < arr.length; i++) { 
    results.push(yield * fn(arr[i])); 
    } 
    return results; 
} 
+0

谢谢!但是,我在昨天解决了一个小时左右后,才真正解决了这个问题。我会将你的答案标记为在未来帮助其他人解决这个问题。 –

+1

太棒了。真高兴你做到了。 :) – Ross

0

很好的例子!提供的示例默认情况下不起作用(来自德国的IP)。

这里一般搜索一点点修正:

const nightmare = require('nightmare'), 
    vo = require('vo'), 
    nbot = nightmare({ 
    title: 'Bot', 
    show: true 
    }); 

const searchTerms = ['spacex', 'tesla', 'elon musk', 'hyperloop']; // EXAMPLE SEARCH TERMS 

vo(run)(function(err) { 
    if (err) throw err 
}); 

function* run() { 
    yield nbot.goto('http://google.com'); 

    var results = yield * forEach(searchTerms, gen); 
    console.log(results); 
    yield nbot.end(); 
} 

function* gen(item) { 
    var inputTitle 
    var value = yield nbot 
    .evaluate(() => { 
     return document.getElementById("lst-ib").title 
    }) 
    .then((lang) => { 
     inputTitle = 'input[title="' + lang + '"]' 
     return true 
    }); 
    yield nbot 
    .wait(inputTitle) 
    .click(inputTitle) 
    .type(inputTitle, item) 
    .click('input[name="btnK"]') 
    .wait(100) 
    .screenshot(item + '.png') 
    .insert(inputTitle, '') 
    .evaluate(function() { 
     return 'foobar' // STUFF RETURNED HERE 
    }); 

    return value; 
} 

function* forEach(arr, fn) { // NEEDED BECAUSE FOREACH DOESN'T WORK IN GENERATORS 
    let i; 
    var results = []; 
    for (i = 0; i < arr.length; i++) { 
    results.push(yield * fn(arr[i])); 
    } 
    return results; 
}