2016-05-31 17 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; 
}