Screenshot of several HTML pages using PhantomJS

Since everyone has mentioned in this github issue , the viewport size function in phantomJS does not behave as expected.

I am trying to take screenshots of an iPad web app. The site has a footer position:fixed;

and header. When I take a screenshot, I only want to see what will be displayed on the screen when the page is first loaded, so I used the following code to copy the page to the size I want.

page.clipRect = { top: 0, left: 0, width: 1024, height: 768 };

      

Since the site has a header and footer position: fixed;

, when I do this and take a screenshot, the footer is missing when the page content forces scrolling. (Bottom right at the bottom of the page)

enter image description here

In the answers, one solution would be to load the page you would like to take a screenshot of into an object with the height and width of your preference, and then take a screenshot for that object.

All code snippets with this are implemented, suppose you have a single URL that you want to take a screenshot of. I would like to take screenshots from several html files. I am not fluent in Javascript at all and I am really trying to combine these solutions into my code.


This solution takes one web page and converts it to multiple differnet size images using a json file.

While this solution is more in line with the strings I'm looking for, but again, only one web page. Note that the iframe does not work and the iframe code must be replaced with an object with a data attribute with the value of the html page being loaded.

And a final solution which is more complete than others, but again this is just one URL


I've used the following code in the past and it worked fine with web apps built for specific dimensions, but this one was built a little differently, so screenshots are a nightmare.

var system = require('system');
var dest = system.args[1];
var files = system.args[2].split(',');

function takeScreenshot(destName, index) {
    var page = require('webpage').create();

    // Open the target HTML file
    page.open(dest+'/'+destName+'/'+destName+'.html', function(status) {

        // Only capture 1024x768 area 
        page.clipRect = { top: 0, left: 0, width: 1024, height: 768 };

        // Save as PNG
        page.render(dest+'/'+destName+'/'+destName+'-full.png');

        // Send output to be caught by progress bar
        console.log('OK');

        // If the lop has finished exit, otherwise clean memory
        if(files.length == 0) {
        phantom.exit();
        } else {
            page.close();
            takeScreenshot(files.shift());
        }
    });

}

takeScreenshot(files.shift());

      

dest is the destination of the screenshots.

files is an array of files that I would like to take a screenshot of.

+3


source to share


1 answer


It should be easy for you to merge the final solution with your existing code. The idea is to move the actual code into a function and call the function with a new url after the previous one completes. When you look at the "final solution", the spots where we left off with the current page are designated phantom.exit();

. From there, you can launch additional screenshots.

Here is the complete script, modified from the DEfusion version:



var args = require('system').args,
    resourceWait  = 300,
    maxRenderWait = 10000,
    mode          = args[3] || 'iframe',
    dest          = args[1],
    files         = args[2].split(','),
    page          = require('webpage').create(),
    count         = 0,
    forcedRenderTimeout,
    renderTimeout;

page.viewportSize = { width: 1024, height : 768 };

function doRender() {
    page.render(filename);
    next();
}

page.onResourceRequested = function (req) {
    count += 1;
    clearTimeout(renderTimeout);
};

page.onResourceReceived = function (res) {
    if (!res.stage || res.stage === 'end') {
        count -= 1;
        if (count === 0) {
            clearTimeout(forcedRenderTimeout);
            renderTimeout = setTimeout(doRender, resourceWait);
        }
    }
};

page.onConsoleMessage = function (msg) {
    console.log("from page: " + msg);
};

function evaluateJsWithArgs(func) {
    var args = [].slice.call(arguments, 1);
    var fn = "function() { return (" + func.toString() + ").apply(this, " + JSON.stringify(args) + "); }";
    return page.evaluate(fn);
};

function next(error){
    if (!error) {
        if (files.length == 0){
            phantom.exit();
        } else {
            takeScreenshot(files.shift());
        }
    }
}

function takeScreenshot(file){
    var url = dest+'/'+file+'/'+file+'.html';
    filename = dest+'/'+file+'/'+file+'-full.png';
    if(mode == 'iframe') {
        // use iFrame
        page.open('about:blank', function (status) {
            if (status !== "success") {
                console.log('Unable to load url');
                next(true);
            } else {
                page.includeJs(
                    "https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js",
                    function() {
                        evaluateJsWithArgs(
                            function(url, w, h) {
                                $('body')
                                    .css({margin: 0, padding: 0})
                                    .append('<object data="' + url + '" width="'+ w + '" height="' + h + '" id="screen-frame" />');
                                $('#screen-frame')
                                    .width(w)
                                    .height(h);
                            },
                            url,
                            page.viewportSize.width,
                            page.viewportSize.height
                        );
                    }
                );

                forcedRenderTimeout = setTimeout(function () {
                    doRender();
                }, maxRenderWait);
            }
        });
    } else {
        // resize body
        page.open(url, function(status) {
            if (status !== "success") {
                console.log('Unable to load url');
                next(true);
            } else {
                page.includeJs(
                    "https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js",
                    function() {
                        evaluateJsWithArgs(
                            function(w,h) {
                               $('body, html').css({
                                    width: w + 'px',
                                    height: h + 'px',
                                    overflow: 'hidden'
                               });
                            },
                            page.viewportSize.width,
                            page.viewportSize.height
                        );

                        forcedRenderTimeout = setTimeout(function () {
                            doRender();
                        }, maxRenderWait);
                    }
                );
            }
        });
    }
}

takeScreenshot(files.shift());

      

0


source







All Articles