【问题标题】:Screenshot of multiple HTML pages using PhantomJS使用 PhantomJS 的多个 HTML 页面的屏幕截图
【发布时间】:2023-04-10 14:42:08
【问题描述】:

正如大家在this github issue 中提到的那样,phantomJS 中的视口大小功能并没有像很多人预期的那样表现。

我正在尝试截取适用于 iPad 的网络应用程序的屏幕截图。该站点有一个position:fixed; 页脚和页眉。当我截取屏幕截图时,我只想在您第一次加载页面时能够看到屏幕上可以看到的内容,所以我使用以下代码将页面剪辑成我想要的大小。

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

因为当我执行此操作并截取屏幕截图时,该站点具有position: fixed; 页眉和页脚,所以当页面上的内容强制滚动时,页脚丢失。 (就在页面底部)

在回复中,一种解决方案是将您想要截屏的页面加载到具有您喜欢的高度和宽度的对象中,然后截取该对象的屏幕截图。

所有实现此功能的代码 sn-ps,假设您有一个想要截取屏幕截图的 URL。我想截取多个 html 文件的屏幕截图。我根本不精通 Javascript,我真的很难将这些解决方案合并到我的代码中。


This solution 获取单个网页并使用 json 文件将其转换为多个不同大小的图像。

虽然this solution 更符合我正在寻找的路线,但同样只是一个网页。请注意,iframe 不起作用,需要将 iframe 代码替换为具有要加载的 html 页面值的 data 属性的对象。

还有一个final solution,它比其他的更完整,但又只是一个 URL


我过去一直在使用以下代码,它与构建到特定尺寸的 Web 应用程序完美配合,但这个代码的构建方式略有不同,这就是为什么屏幕截图是一场噩梦。

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 变量是截图的目的地。

files 是我要截屏的文件数组。

【问题讨论】:

    标签: javascript phantomjs screenshot


    【解决方案1】:

    final solution 与您现有的代码结合起来应该很容易。这个想法是将实际代码移动到一个函数中,并在前一个完成后使用新 URL 调用该函数。当您查看“最终解决方案”时,我们完成当前页面的位置用phantom.exit(); 表示。从那里你可以触发更多的截图。

    这是完整的脚本,从 DEfusion 版本修改:

    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());
    

    【讨论】:

    • 啊,我真的希望这会奏效。但不幸的是它不是:(。因为我将它作为 grunt 任务的一部分运行,所以在控制台日志获取输出时调试它真的很棘手。你能推荐任何在 grunt 之外运行它的方法吗?非常感谢。
    • 什么意思,它不起作用。这句话绝对没有任何信息。请更具体。我注意到 iframe 变体不适用于本地文件。我没有使用 grunt 的经验,所以我无法帮助你。
    • 对不起,我知道这是一个糟糕的回应,但因为我无法记录任何内容,因为它在咕噜声中运行,我不知道还能说什么。所以我把这个脚本从 grunt 中取出来尝试使用 phantomjs screenshot.js 直接从终端运行它。我已经用 grunt 将传递给 screenshot.js 文件的值替换了所有系统参数。当我运行此命令时,我会在控制台中看到 CoreText 性能说明。我正在创建目标目录图像文件,但它们不包含任何屏幕截图,只是一个完全空白的图像。我会继续尝试调试这个。
    • 我创建了一个测试 html 页面,只是为了确保该对象实际上使页面按预期显示。确实如此。我已经注销了 URL、文件名的变量,一切似乎都正常。仍然难倒
    • 我感觉这可能与参考文件位置的页面位置有关。我正在以下文件位置执行此屏幕截图脚本。根/工具/screenshot.js。我在其中截屏的页面位于 root/dist/files.html 中。你知道文件位置是我运行脚本的位置(例如根目录)还是脚本所在的位置(root/tools/screenshot.js)的引用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-15
    • 1970-01-01
    • 2015-10-30
    • 1970-01-01
    相关资源
    最近更新 更多