Skip to content

Instantly share code, notes, and snippets.

@sawantuday
Created April 26, 2016 11:02
Show Gist options
  • Select an option

  • Save sawantuday/55c80a583cef968d7c0042d37cf5d3b1 to your computer and use it in GitHub Desktop.

Select an option

Save sawantuday/55c80a583cef968d7c0042d37cf5d3b1 to your computer and use it in GitHub Desktop.
Another approach for dynamic waiting timeouts to allow the page to fully load before rendering. Instead of waiting fixed amount of time before rendering, It give a short time for the page to make additional requests.
// PhantomJS script
// Takes screeshot of a given page. This correctly handles pages which
// dynamically load content making AJAX requests.
// Instead of waiting fixed amount of time before rendering, we give a short
// time for the page to make additional requests.
// Origin https://github.com/kimmobrunfeldt/url-to-image/blob/master/src/url-to-image.js
// Phantom internals
var system = require('system');
var webPage = require('webpage');
function main() {
// I tried to use yargs as a nicer commandline option parser but
// it doesn't run in phantomjs environment
var args = system.args;
var opts = {
url: args[1],
filePath: args[2],
width: args[3],
height: args[4],
requestTimeout: args[5],
maxTimeout: args[6],
verbose: args[7] === 'true',
fileType: args[8],
fileQuality: args[9] ? args[9] : 100,
cropWidth: args[10],
cropHeight: args[11],
cropOffsetLeft: args[12] ? args[12] : 0,
cropOffsetTop: args[13] ? args[13] : 0
};
renderPage(opts);
}
function renderPage(opts) {
var requestCount = 0;
var forceRenderTimeout;
var dynamicRenderTimeout;
var page = webPage.create();
page.viewportSize = {
width: opts.width,
height: opts.height
};
// Silence confirmation messages and errors
page.onConfirm = page.onPrompt = function noOp() {};
page.onError = function(err) {
log('Page error:', err);
};
page.onResourceRequested = function(request) {
log('->', request.method, request.url);
requestCount += 1;
clearTimeout(dynamicRenderTimeout);
};
page.onResourceReceived = function(response) {
if (!response.stage || response.stage === 'end') {
log('<-', response.status, response.url);
requestCount -= 1;
if (requestCount === 0) {
dynamicRenderTimeout = setTimeout(renderAndExit, opts.requestTimeout);
}
}
};
page.open(opts.url, function(status) {
if (status !== 'success') {
log('Unable to load url:', opts.url);
phantom.exit(10);
} else {
forceRenderTimeout = setTimeout(renderAndExit, opts.maxTimeout);
}
});
function log() {
// PhangomJS doesn't stringify objects very well, doing that manually
if (opts.verbose) {
var args = Array.prototype.slice.call(arguments);
var str = '';
args.forEach(function(arg) {
if (isString) {
str += arg;
} else {
str += JSON.stringify(arg, null, 2);
}
str += ' '
});
console.log(str);
}
}
function renderAndExit() {
log('Render screenshot..');
if(opts.cropWidth && opts.cropHeight) {
log("Cropping...");
page.clipRect = {top: opts.cropOffsetTop, left: opts.cropOffsetLeft, width: opts.cropWidth, height: opts.cropHeight};
}
var renderOpts = {
fileQuality: opts.fileQuality
};
if(opts.fileType) {
log("Adjusting File Type...");
renderOpts.fileType = opts.fileType;
}
page.render(opts.filePath, renderOpts);
log('Done.');
phantom.exit();
}
}
function isString(value) {
return typeof value == 'string'
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment