Batch Rendering Screenshots with PhantomJS

There are 1001 ways to skin this cat, from browser plugins to dedicated apps, to just using the "command+shift+4" shortcut on your mac. However, if I want to take multiple screenshots at once, I prefer the most automated way possible.

PhantomJS describes itself as a "headless WebKit scriptable". I don't think "scriptable" is a noun, so I'd just call it a "browser that runs in the command line". You can use PhantomJS for a lot of stuff, but all we need is the great screen capture functionality.

The code below will render screenshots from an array of URLs. We specify the default width and height of the screenshots, and wait 5 seconds between each screenshot. The wait time is there so that phantomJS has time to load the page. This is handy on advanced pages that use AJAX to load in content.

To make sure we get the entire content of the page in our screenshot, we try to match the height of the screenshot to the height of the body element on the page. Sometimes though, the body and html element heights are set to "100%". In these cases, the screenshot will render with the default page height of 900px.


var URLS = ["https://google.com",
            "http://www.bing.com/",
            "https://www.yahoo.com/"
            ]

var SCREENSHOT_WIDTH = 1280; 
var SCREENSHOT_HEIGHT = 900; 
var LOAD_WAIT_TIME = 5000; 

var getPageTitle = function(page){
    var documentTitle = page.evaluate(function(){
        return document.title; 
    })
    console.log("getting title:", documentTitle)
    return documentTitle; 
}

var getPageHeight = function(page){
    var documentHeight = page.evaluate(function() { 
        return document.body.offsetHeight; 
    })
    console.log("getting height:", documentHeight)
    return documentHeight; 
}

var renderPage = function(page){

    var title =  getPageTitle(page);

    var pageHeight = getPageHeight(page); 

    page.clipRect = {
        top:0,left:0,width: SCREENSHOT_WIDTH, 
        height: pageHeight
    };
    page.render(title+".png");
    console.log("rendered:", title+".png")
}

var exitIfLast = function(index,array){
    console.log(array.length - index-1, "more screenshots to go!")
    console.log("~~~~~~~~~~~~~~")
    if (index == array.length-1){
        console.log("exiting phantomjs")
        phantom.exit();
    }
}

var takeScreenshot = function(element){

    console.log("opening URL:", element)

    var page = require("webpage").create();

    page.viewportSize = {width:SCREENSHOT_WIDTH, height:SCREENSHOT_HEIGHT};

    page.open(element); 

    console.log("waiting for page to load...")

    page.onLoadFinished = function() {
        setTimeout(function(){
            console.log("that's long enough")
            renderPage(page)
            exitIfLast(index,URLS)
            index++; 
            takeScreenshot(URLS[index]);
        },LOAD_WAIT_TIME)
    }

}

var index = 0; 

takeScreenshot(URLS[index]);