节点 – 骑手未处理的拒绝评估

我正在尝试用Node-horseman编写一个基本的网页抓取工具,但是我在评估函数中遇到了CSSselect器的一些问题。 有些网站的评估函数工作得很好,但是对于其他的网站,Node会抛出一个错误。

例如:

var Horseman = require('node-horseman'); var horseman = new Horseman(); function getTitle() { var title = $('.product-name-main h1').text(); return {title: title}; } horseman .userAgent('Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0') .open('http://shtoraoptom.ru/pokryvalo-nazsu-gul-abrikosovyj-240-260-sm') .evaluate(getTitle) .then(function(title){ console.log(title); return horseman.close(); }); 

这段代码会抛出一个错误:

 Unhandled rejection getTitle evaluate global code evaluateJavaScript@[native code] evaluate@phantomjs://platform/webpage.js:390:39 phantomjs://code/bridge.js:121:61 at Horseman.<anonymous> (/home/ubuntu/workspace/node_modules/node-horseman/lib/actions.js:839:38) at Horseman.tryCatcher (/home/ubuntu/workspace/node_modules/node-horseman/node_modules/bluebird/js/release/util.js:16:23) at Promise._settlePromiseFromHandler (/home/ubuntu/workspace/node_modules/node-horseman/node_modules/bluebird/js/release/promise.js:502:31) at Promise._settlePromise (/home/ubuntu/workspace/node_modules/node-horseman/node_modules/bluebird/js/release/promise.js:559:18) at Promise._settlePromiseCtx (/home/ubuntu/workspace/node_modules/node-horseman/node_modules/bluebird/js/release/promise.js:596:10) at Async._drainQueue (/home/ubuntu/workspace/node_modules/node-horseman/node_modules/bluebird/js/release/async.js:143:12) at Async._drainQueues (/home/ubuntu/workspace/node_modules/node-horseman/node_modules/bluebird/js/release/async.js:148:10) at Immediate.Async.drainQueues [as _onImmediate] (/home/ubuntu/workspace/node_modules/node-horseman/node_modules/bluebird/js/release/async.js:17:14) at processImmediate [as _immediateCallback] (timers.js:383:17) 

当我尝试用另一种方式使用相同的select器重写代码时,它会正确地注销标题:

 var Horseman = require('node-horseman'); var horseman = new Horseman(); function getTitle() { var title = $('.product-name-main h1').text(); return {title: title}; } horseman .userAgent('Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0') .open('http://shtoraoptom.ru/pokryvalo-nazsu-gul-abrikosovyj-240-260-sm') .text('.product-name-main h1') .then(function(title){ console.log(title); return horseman.close(); }); 

什么可能是这种types的错误的原因?

原因

.evaluate()方法期望客户端JavaScript函数在您正在抓取的网页中可用。

你在第一个例子中定义getTitle()函数的方式意味着它是在NodeJS范围内创build的,而不是在刮取的网页客户端范围内。


可能的修复

选项1

你可以摆脱创buildgetTitle()函数,但是将.evaluate()方法的参数写入客户端JavaScript代码,如下所示:

 .evaluate(function () { return $('.product-name h1').first().text(); }) 

(为完整的解决scheme请检查我的GitHub回购: https : //github.com/omnimind/stackOverflow/blob/master/NodeJS/Controllers/37793821.js脚本方法称为main()

scheme2

如果你坚持创buildgetTitle() JavaScript函数,那么你将需要在一个单独的JavaScript文件中创build函数,并通过使用.injectJs(file)像这样将其注入到您正在抓取的网页中:

 .injectJs('<external_javascript_file>').evaluate(function () { return getTitle(); }) 

(完整的解决scheme,请检查我的GitHub回购: https : //github.com/omnimind/stackOverflow/blob/master/NodeJS/Controllers/37793821.js脚本方法称为external()


备注

第二个选项允许您更好地组织代码,特别是在您需要注入的客户端JavaScript代码由于其大小而变得更加复杂和强大的情况下。