Ответ 1
После подпрыгивания этого в течение некоторого времени я смог сузить проблему. По-видимому, PhantomJS использует по умолчанию ssl sslv3
, из-за чего github отказывается от соединения из-за плохого ssl handshake
phantomjs --debug=true github.js
Показывает вывод:
. . .
2014-10-22T19:48:31 [DEBUG] WebPage - updateLoadingProgress: 10
2014-10-22T19:48:32 [DEBUG] Network - Resource request error: 6 ( "SSL handshake failed" ) URL: "https://github.com/"
2014-10-22T19:48:32 [DEBUG] WebPage - updateLoadingProgress: 100
Итак, из этого можно сделать вывод, что экран не был взят, потому что github отказывался от связи. Отлично, что имеет смысл. Поэтому давайте установить флаг SSL в --ssl-protocol=any
и также игнорировать ssl-ошибки с помощью --ignore-ssl-errors=true
phantomjs --ignore-ssl-errors=true --ssl-protocol=any --debug=true github.js
Большой успех! Снимок экрана теперь отображается и сохраняется должным образом, но отладчик показывает нам TypeError:
TypeError: 'undefined' is not a function (evaluating 'Array.prototype.forEach.call.bind(Array.prototype.forEach)')
https://assets-cdn.github.com/assets/frameworks-dabc650f8a51dffd1d4376a3522cbda5536e4807e01d2a86ff7e60d8d6ee3029.js:29
https://assets-cdn.github.com/assets/frameworks-dabc650f8a51dffd1d4376a3522cbda5536e4807e01d2a86ff7e60d8d6ee3029.js:29
2014-10-22T19:52:32 [DEBUG] WebPage - updateLoadingProgress: 72
2014-10-22T19:52:32 [DEBUG] WebPage - updateLoadingProgress: 88
ReferenceError: Can't find variable: $
https://assets-cdn.github.com/assets/github-fa2f009761e3bc4750ed00845b9717b09646361cbbc3fa473ad64de9ca6ccf5b.js:1
https://assets-cdn.github.com/assets/github-fa2f009761e3bc4750ed00845b9717b09646361cbbc3fa473ad64de9ca6ccf5b.js:1
Я проверил домашнюю страницу github вручную, чтобы увидеть, существует ли TypeError, и это НЕ.
Моя следующая догадка заключается в том, что активы не загружаются достаточно быстро.. Phantomjs быстрее, чем ускоряющая пуля!
Итак, попытайтесь искусственно замедлить его и посмотреть, можем ли мы избавиться от этого TypeError...
var page = require('webpage').create();
page.settings.userAgent = 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36';
page.open('http://github.com', function (status) {
window.setTimeout(function () {
page.render('github.png');
phantom.exit();
}, 3000);
});
Это не сработало... После более пристального осмотра изображения - ясно, что некоторые элементы отсутствуют. Главным образом некоторые значки и логотип.
Успех? Частично потому, что мы сейчас, по крайней мере, снимаем экран раньше, мы ничего не получали.
Работа выполнена? Не совсем. Необходимо определить, что вызывает это TypeError, потому что это мешает некоторым активам загружать и искажать изображение.
Дополнительно
Попытка воссоздать с помощью CasperJS --debug очень уродлива и сложна в сравнении с PhantomJS:
casper.start();
casper.userAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X)');
casper.thenOpen('https://www.github.com/', function() {
this.captureSelector('github.png', 'body');
});
casper.run();
Приставки:
casperjs test --ssl-protocol=any --debug=true github.js
Далее на изображении отсутствуют одинаковые значки, но также визуально искажены. Поскольку CasperJs полагается на Phantomjs, я не вижу смысла использовать его для этой конкретной задачи.
Если вы хотите добавить к моему ответу, поделитесь своими результатами. Очень заинтересован в безупречном решении PhantomJS
Обновление # 1: Удаление TypeError
@ArtjomB указывает, что Phantomjs не поддерживает js bind
в текущей версии этого обновления (1.9.7). По этой причине он объясняет: ArtjomB: PhantomJs Bind Issue Answer
TypeError: 'undefined' не является функцией, ссылающейся на bind, потому что PhantomJS 1.x не поддерживает его. PhantomJS 1.x использует старую вилку QtWebkit, который сопоставим с Chrome 13 или Safari 5. Новее PhantomJS 2 будет использовать более новый движок, который будет поддерживать привязку. На данный момент вам нужно добавить прокладку внутри страницы. inInitialized обработчик событий:
Хорошо, так что следующий код позаботится о нашем TypeError
сверху. (Но не полностью функциональный, см. Ниже для деталей)
var page = require('webpage').create();
page.settings.userAgent = 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36';
page.open('http://github.com', function (status) {
window.setTimeout(function () {
page.render('github.png');
phantom.exit();
}, 5000);
});
page.onInitialized = function(){
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;
}
});
}
Теперь приведенный выше код даст нам скриншот того же самого, что и мы до этого. И отладка не покажет TypeError
, так что с поверхности все работает. Прогресс был достигнут.
К сожалению, все значки изображений [логотип и т.д.] по-прежнему не загружаются правильно. Мы видим, что какой-то значок 3W не уверен, откуда это.
Спасибо за помощь @ArtjomB