12月07, 2017

PhantomJS截图实践

PhantomJS是一个无界面的,可脚本编程的WebKit浏览器引擎。它原生支持多种web 标准:DOM 操作,CSS选择器,JSON,Canvas 以及SVG。

有时候我们需要浏览器处理网页,却不需要视图浏览。比如网页截图、抓取SPA网站、自动化测试等操作。这个时候就用得上PhantomJS了,它可以加载一个无界面的网页,同时我们又可以通过代码来操作这个网页。

接下来,一起体验下这个神奇好用的工具。

安装

我是使用npm安装的,比较快捷方便,傻瓜式安装。

npm install phantomjs -g
phantomjs -v

当然你也可以在官网下载编译好的二进制文件,或者不嫌麻烦的,可以自己编译。

截图DEMO

/*loadpage.js*/
var system = require('system');
var page = require('webpage').create();

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

var url = system.args[1];
var imagePath = system.args[2];

page.open(url, function(status) {
    if (status === "success") {
        var title = page.evaluate(function() {
            return document.title;
        });
        page.render(imagePath, {
            format: 'png',
            quality: '85'
        });
        console.log(imagePath);
    } else {
        console.log('');
    }
    phantom.exit(1);
});

控制台运行:

phantomjs loadpage.js https://luodao.me luodao.png

代码比较简单,读一遍大概就知道是什么意思了。

其中webpage这个库是phantomjs的核心模块,用于网页操作。以上,实现了从命令行读取两个参数,system.args[1] 表示要抓取的链接,system.args[2]表示截图存储路径。

效果如下:

alt

遇到的问题

使用中还是遇到几个问题。

找不到webpage模块

一开始直接把phantomjs代码写在node中,用node来运行,报了一个找不到webpage模块的错误:

Cannot find module 'webpage'

其原因是,webpage是一个phantomjs的模块,并不是一个npm包,是无法直接在node里面使用的。node中可以使用调用子进程的方法来调用这个phantomjs脚本。

// 开启一个phantomjs子进程
const phantom = child_process.spawn('phantomjs', 'loadpage.js', 'https://luodao.me', 'luodao.png']);

// 设置stdout字符编码
phantom.stdout.setEncoding('utf8');

return new Promise((resolve, reject) => {
    phantom.stdout.on('data', function(data) {
        resolve(data);
    });
});

谷歌上的解释如下:

alt

截图乱码

在我MAC上运行的时候发现截图效果还可以的,但是放到ECS上后,发现截图出来图片里面竟然都是乱码的,效果就跟下面的差不多。

alt

引起乱码的原因是因为ESC上缺少了部分字体,文字没办法渲染,才导致了这个乱码。

yum install bitmap-fonts bitmap-fonts-cjk //centos
apt-get install xfonts-wqy //ubuntu

安装了这些字体后,基本不会出现乱码,但是还是会有字体粗细不一致的问题。因为服务器上还是缺少很多字体的,解决方案就是把那些常用的字体都给安装上。

图片质量和文件大小

page.render(imagePath, {
    format: 'png',
    quality: '85'
});

截图生成函数中,有一个quality参数,这个参数控制了生成图片的质量,100最高,图片质量也最好。

但是需要注意,调到100的时候,图片特别大,我这里生成的图片有3M多,这个图片放到网站上肯定是不现实的。经过调整,我最终选了85这个质量参数,生成的图片只有200K左右,效果也比较合适,最少肉眼看上去差别不大。

headless 和 puppeteer

说了这么多,其实我想推荐headless 和 puppeteer,headless是谷歌新推出的类phantomjs工具,puppeteer是headless的一个使用封装。

之所以推荐这两个东西是因为,phantomjs用的是比较老的WebKit来实现的,效果和性能已经有些跟不上了,可以多尝试一下新品。

最后放一张使用headless截的图,效果还是不错的。有兴趣的朋友可以自行了解下。

alt

puppeteer相关安装和使用教程可以看这里centos安装puppeteer爬坑

本文链接:https://luodao.me/post/phantomjs-shijian.html

-- EOF --

Comments