节点 – 骑手未处理的拒绝评估
我正在尝试用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代码由于其大小而变得更加复杂和强大的情况下。