Matheus S. Rossi Matheus S. Rossi - 3 years ago 208
Javascript Question

cant run FOR loops inside .evaluate (node-horseman / phantomjs)

Hello Everyone!

I am trying to do do a web-crawler with node-horseman, that make easier do work with phantomJS. But I am stuck at one point.

Apparently, i can't run for loops inside .evaluate, is it right?

The gist with my code:

As you can see, if i run exactly the same code in the browser, everything works fine, like in this image:

Code running OK in the browser

But if i run the code in node-horseman, i get this:

Unhandled rejection eval@[native code]

global code
evaluateJavaScript@[native code]
phantomjs://code/bridge.js:121:61 at Horseman.<anonymous>
at Horseman.tryCatcher (/home/matheus/Documentos/NodeJs/node-horseman/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/home/matheus/Documentos/NodeJs/node-horseman/node_modules/bluebird/js/release/promise.js:512:31)
at Promise._settlePromise (/home/matheus/Documentos/NodeJs/node-horseman/node_modules/bluebird/js/release/promise.js:569:18)
at Promise._settlePromiseCtx (/home/matheus/Documentos/NodeJs/node-horseman/node_modules/bluebird/js/release/promise.js:606:10)
at Async._drainQueue (/home/matheus/Documentos/NodeJs/node-horseman/node_modules/bluebird/js/release/async.js:138:12)
at Async._drainQueues (/home/matheus/Documentos/NodeJs/node-horseman/node_modules/bluebird/js/release/async.js:143:10)
at Immediate.Async.drainQueues (/home/matheus/Documentos/NodeJs/node-horseman/node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:781:20)
at tryOnImmediate (timers.js:743:5)
at processImmediate [as _immediateCallback] (timers.js:714:5)

This is my code in index.js, that runs node-horseman

var Horseman = require('node-horseman')
var horseman = new Horseman()


const descNode = document.querySelectorAll('.descr a')
const desc =, function (t) { return t.textContent })

const valueNode = document.querySelectorAll('.price a')
const value =, function (t) { return t.textContent })

const finalData = []

for (let i=0 ; i < desc.length; i ++) {
let item = {}
item['desc'] = desc[i]
item['value'] = value[i]

return finalData


What am i missing ?

Edit - After including .catch in the promise, got this new information:

message: 'Expected an identifier but found \'item\' instead',

Answer Source

The thing you are missing is that phantom.js is running javascript in a different environment than node. Like many browsers, not all of the nice es6 language features are available in this environment (yet).

If I run your code , I get errors from phantom.js with the use of let. Changing those to var makes your code work for me.

Also, it's a good idea to add .catch() after the promise, because then you'll get better errors, which may have been useful in this situation.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download