Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 706|回复: 0

利用PhantomJS进行网页截屏,完美解决截取高度的问题

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-7-1 00:24:09 | 显示全部楼层 |阅读模式

    关于PhantomJS

    PhantomJS 是一个基于WebKit的服务器端 JavaScript API。它全面支持web而不需浏览器支持,其快速,原生支持各种Web标准: DOM 处理, CSS 选择器, JSON, Canvas, 和 SVG。PhantomJS可以用于页面自动化,网络监测,网页截屏,以及无界面测试等。

    我们还可以用它来做爬虫哦,大家知道,网页上有些数据是通过执行js渲染出来的,这样的话爬虫去抓取数据的时候就会很麻烦,PhantomJS自带WebKit内核,我们可以利用PhantomJS解决爬虫不能执行js的问题。

    这次要说的是他的截图功能

    下面是官网提供的rasterize.js截图示例:

    var page = require('webpage').create(),
        system = require('system'),
        address, output, size;
    
    if (system.args.length < 3 || system.args.length > 5) {
        console.log('Usage: rasterize.js URL filename [paperwidth*paperheight|paperformat] [zoom]');
        console.log('  paper (pdf output) examples: "5in*7.5in", "10cm*20cm", "A4", "Letter"');
        console.log('  image (png/jpg output) examples: "1920px" entire page, window width 1920px');
        console.log('                                   "800px*600px" window, clipped to 800x600');
        phantom.exit(1);
    } else {
        address = system.args[1];
        output = system.args[2];
        page.viewportSize = { width: 600, height: 600 };
        if (system.args.length > 3 && system.args[2].substr(-4) === ".pdf") {
            size = system.args[3].split('*');
            page.paperSize = size.length === 2 ? { width: size[0], height: size[1], margin: '0px' }
                                               : { format: system.args[3], orientation: 'portrait', margin: '1cm' };
        } else if (system.args.length > 3 && system.args[3].substr(-2) === "px") {
            size = system.args[3].split('*');
            if (size.length === 2) {
                pageWidth = parseInt(size[0], 10);
                pageHeight = parseInt(size[1], 10);
                page.viewportSize = { width: pageWidth, height: pageHeight };
                // 通过clipRect可以指定渲染的区域:
                page.clipRect = { top: 0, left: 0, width: pageWidth, height: pageHeight };
            } else {
                console.log("size:", system.args[3]);
                pageWidth = parseInt(system.args[3], 10);
                pageHeight = parseInt(pageWidth * 3/4, 10); // it's as good an assumption as any
                console.log ("pageHeight:",pageHeight);
                page.viewportSize = { width: pageWidth, height: pageHeight };
            }
        }
        if (system.args.length > 4) {
            page.zoomFactor = system.args[4];
        }
        page.open(address, function (status) {
            if (status !== 'success') {
                console.log('Unable to load the address!');
                phantom.exit(1);
            } else {
                window.setTimeout(function () {
                    page.render(output);
                    phantom.exit();
                }, 200);
            }
        });
    }

     

     

    上面的代码可以进行截图,不过问题就在于,页面的高度需要我们手动指定,那就不方便了。

    在园子里发现有个哥们通过手动设定高度的方法来解决这个问题:http://www.cnblogs.com/xiehuiqi220/p/3551699.html,不过页面的高度没有那么高,渲染的图片下面就会出现大块的留白,也是不够灵活。

    想到PhantomJS本身也可以执行js的,我们可以将页面加载完毕后,获取页面的实际高度,然后重新设定截取的区域,不就可以解决了。

    于是便有了以下代码:

    // 通过在页面上执行脚本获取页面的渲染高度
    var bb = page.evaluate(function () { 
      return document.getElementsByTagName('html')[0].getBoundingClientRect(); 
    });
    // 按照实际页面的高度,设定渲染的宽高
    page.clipRect = {
      top:    bb.top,
      left:   bb.left,
      width:  bb.width,
      height: bb.height
    };
    // 预留一定的渲染时间
    window.setTimeout(function () {
      page.render(file);
      page.close();
      console.log('render ok');
    }, 1000);

     

     

    改造后的代码如下:

    var page = require('webpage').create(),
        system = require('system'),
        address, output, size;
    
    if (system.args.length < 3 || system.args.length > 5) {
        console.log('Usage: rasterize.js URL filename');
        phantom.exit(1);
    } else {
        address = system.args[1];
        output = system.args[2];
        page.viewportSize = { width: 1024, height: 600 };
        page.open(address, function (status) {
          // 通过在页面上执行脚本获取页面的渲染高度
          var bb = page.evaluate(function () { 
            return document.getElementsByTagName('html')[0].getBoundingClientRect(); 
          });
          // 按照实际页面的高度,设定渲染的宽高
          page.clipRect = {
            top:    bb.top,
            left:   bb.left,
            width:  bb.width,
            height: bb.height
          };
          // 预留一定的渲染时间
          window.setTimeout(function () {
            page.render(output);
            page.close();
            console.log('render ok');
         phantom.exit(); }
    , 1000); }); }

     

     

    通过执行

    D:\Software\phantomjs-1.9.7-windows>phantomjs.exe render.js http://cnblogs.com cnblogs.png

     

    就可以把博客园首页截取下来了。

    效果如下:

    PhantomJS内置一个小型的Web服务器,我们可以将其封装成服务,这里就不过多介绍了,大家可以移步这里:http://www.jb51.net/article/43328.htm

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-12-23 08:19 , Processed in 0.058736 second(s), 30 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表