我正在尝试使用PhantomJS和Node.js截取earth.nullschool.net。
这是相关代码:
var phantom = require("phantom");
var url = "http://earth.nullschool.net/#current/wind/isobaric/10hPa/orthographic=0.00,0.00,350";
var timeout = 15000;
phantom.create(function(ph) {
ph.createPage(function(page) {
page.open(url, function(status) {
setTimeout(function() {
page.render("earth_0-0-350_#current.png", function(finished) {
ph.exit();
});
}, timeout);
});
});
});
我最初将timeout
变量设置为5秒。这返回了一个未渲染地图的空白图像。
earth not rendered http://i59.tinypic.com/mma8ue.png
我认为我需要更长的超时才能让页面完全加载。所以我逐渐将超时时间延长到一分钟。但输出是一样的。地图永远不会呈现。
注册事件处理程序(onConsoleMessage
,onError
,onResourceError
,onResourceTimeout
后),我发现以下错误:
ERROR: TypeError: 'undefined' is not a function (evaluating 'i.bind(null,t,n)')
TRACE:
-> http://earth.nullschool.net/js/bundle.min.js?v20150923: 84
-> http://earth.nullschool.net/js/bundle.min.js?v20150923: 85
-> http://earth.nullschool.net/js/bundle.min.js?v20150923: 85
-> http://earth.nullschool.net/js/bundle.min.js?v20150923: 7 (in function "a")
-> http://earth.nullschool.net/js/bundle.min.js?v20150923: 7
-> http://earth.nullschool.net/js/bundle.min.js?v20150923: 84 (in function "n")
-> http://earth.nullschool.net/js/bundle.min.js?v20150923: 64
答案 0 :(得分:2)
PhantomJS 1.x有一个非常古老的引擎,并不支持一些基本的Web标准。其中包括Function.prototype.bind
,不受支持。 This shim适用于几乎所有情况。
由于您通常希望尽快启用此功能,因此必须从page.onInitialized
事件侦听器运行填充程序。 phantomjs-node中的调用与普通PhantomJS中的调用略有不同:
phantom.create(function (ph) {
ph.createPage(function (page) {
page.set('onInitialized', function(success) {
page.evaluate(function(){
var isFunction = function(o) {
return typeof o == 'function';
};
var bind,
slice = [].slice,
proto = Function.prototype,
featureMap;
featureMap = {
'function-bind': 'bind'
};
function has(feature) {
var prop = featureMap[feature];
return isFunction(proto[prop]);
}
// check for missing features
if (!has('function-bind')) {
// adapted from Mozilla Developer Network example at
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
bind = function bind(obj) {
var args = slice.call(arguments, 1),
self = this,
nop = function() {
},
bound = function() {
return self.apply(this instanceof nop ? this : (obj || {}), args.concat(slice.call(arguments)));
};
nop.prototype = this.prototype || {}; // Firefox cries sometimes if prototype is undefined
bound.prototype = new nop();
return bound;
};
proto.bind = bind;
}
});
});
/* remaining script */
setTimeout(function() {
page.render("earth_0-0-350_#current.png", function(finished) {
ph.exit();
});
}, timeout);
});
});
根据我的回答here进行调整。