使用PhantomJS实现网页截图服务
2015-09-09 21:51
726 查看
这是上半年遇到的一个小需求,想实现网页的抓取,并保存为图片。研究了不少工具,效果都不理想,不是显示太差了(Canvas、Html2Image、Cobra),就是性能不怎么样(如SWT的Brower)。后发现无界面浏览器可以满足这个条件,大致研究了一下PhantomJS与CutyCapt,两者都是Webkit内核,其中PhantomJS使用上更方便一些,尤其在Windows平台上,如果在Linux下,从2.0版本后需要自己去机器上编译了(大概要编译3个小时,不得不说,g++就是个渣渣,同样的项目,在vc下编译快得,不谈了,毕竟是免费开源的编译器)。下面介绍PhantomJS结合Java代码实现的网页截图技术:
一、环境准备
1、PhantomJS脚本的目录:D:/xxx/phantomjs-2.0.0-windows/bin/phantomjs
2、截图脚本:D:/xxx/phantomjs-2.0.0-windows/bin/rasterize.js
截图的脚本在官网上有提供,但是我这里需要说明一下它的高宽度设计原理:
这个是默认的高度,也就是600X600,我建议大家把height设置小一点,我这边设置的是width:800,height:200。因为实际上,在不同时设置高度与亮度的情况下,如果真实的网页的高度大于设置值时,图片会自动扩充高宽度的,直到整个页面显示完(当你想截取小的图片时,可能由于默认设置的太大,会使图片有很大一块空的)。如果同时设置了高宽度,下面的代码会被执行,就会对网页的部分进行截取了:
3、先用命令行测试一下:
如果配置好了,应该可以看到生成的图片了。当然还可以配置高宽度的参数,在上面的命令后加上:" 1000px"或" 1000px*400px",都是可以的。
二、服务器代码
作为一个网页截图服务,这部分代码片段应当被布署在服务器上,当然不必全照搬啦,根据自己的需求来用就好了:
使用上面的PhantomTools类,可以很方便地调用getByteImg方法来生成并获取图片内容。
附上我的截图配置脚本:rasterize.js,至于PhantomJS,大家就自行去官网下载吧。
转载请注明原址:/article/5813055.html
一、环境准备
1、PhantomJS脚本的目录:D:/xxx/phantomjs-2.0.0-windows/bin/phantomjs
2、截图脚本:D:/xxx/phantomjs-2.0.0-windows/bin/rasterize.js
截图的脚本在官网上有提供,但是我这里需要说明一下它的高宽度设计原理:
page.viewportSize = { width: 600, height: 600 };
这个是默认的高度,也就是600X600,我建议大家把height设置小一点,我这边设置的是width:800,height:200。因为实际上,在不同时设置高度与亮度的情况下,如果真实的网页的高度大于设置值时,图片会自动扩充高宽度的,直到整个页面显示完(当你想截取小的图片时,可能由于默认设置的太大,会使图片有很大一块空的)。如果同时设置了高宽度,下面的代码会被执行,就会对网页的部分进行截取了:
page.clipRect = { top: 0, left: 0, width: pageWidth, height: pageHeight };
3、先用命令行测试一下:
D:/xxx/phantomjs-2.0.0-windows/bin/phantomjs D:/xxx/phantomjs-2.0.0-windows/bin/rasterize.js http://www.qq.com D:/test.png
如果配置好了,应该可以看到生成的图片了。当然还可以配置高宽度的参数,在上面的命令后加上:" 1000px"或" 1000px*400px",都是可以的。
二、服务器代码
作为一个网页截图服务,这部分代码片段应当被布署在服务器上,当然不必全照搬啦,根据自己的需求来用就好了:
package lekkoli.test; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import org.apache.log4j.Logger; /** * 网页转图片处理类,使用外部CMD * @author lekkoli */ public class PhantomTools { private static final Logger _logger = Logger.getLogger(PhantomTools.class); // private static final String _tempPath = "/data/temp/phantom_"; // private static final String _shellCommand = "/usr/local/xxx/phantomjs /usr/local/xxx/rasterize.js "; Linux下的命令 private static final String _tempPath = "D:/data/temp/phantom_"; private static final String _shellCommand = "D:/xxx/phantomjs-2.0.0-windows/bin/phantomjs D:/xxx/phantomjs-2.0.0-windows/bin/rasterize.js "; private String _file; private String _size; /** * 构造截图类 * @parm hash 用于临时文件的目录唯一化 */ public PhantomTools(int hash) { _file = _tempPath + hash + ".png"; } /** * 构造截图类 * @parm hash 用于临时文件的目录唯一化 * @param size 图片的大小,如800px*600px(此时高度会裁切),或800px(此时 高度最少=宽度*9/16,高度不裁切) */ public PhantomTools(int hash, String size) { this(hash); if (size != null) _size = " " + size; } /** * 将目标网页转为图片字节流 * @param url 目标网页地址 * @return 字节流 */ public byte[] getByteImg(String url) throws IOException { BufferedInputStream in = null; ByteArrayOutputStream out = null; File file = null; byte[] ret = null; try { if (exeCmd(_shellCommand + url + " " + _file + (_size != null ? _size : ""))) { file = new File(_file); if (file.exists()) { out = new ByteArrayOutputStream(); byte[] b = new byte[5120]; in = new BufferedInputStream(new FileInputStream(file)); int n; while ((n = in.read(b, 0, 5120)) != -1) { out.write(b, 0, n); } file.delete(); ret = out.toByteArray(); } } else { ret = new byte[] {}; } } finally { try { if (out != null) { out.close(); } } catch (IOException e) { _logger.error(e); } try { if (in != null) { in.close(); } } catch (IOException e) { _logger.error(e); } if (file != null && file.exists()) { file.delete(); } } return ret; } /** * 执行CMD命令 */ private static boolean exeCmd(String commandStr) { BufferedReader br = null; try { Process p = Runtime.getRuntime().exec(commandStr); if (p.waitFor() != 0 && p.exitValue() == 1) { return false; } } catch (Exception e) { _logger.error(e); } finally { if (br != null) { try { br.close(); } catch (Exception e) { _logger.error(e); } } } return true; } }
使用上面的PhantomTools类,可以很方便地调用getByteImg方法来生成并获取图片内容。
附上我的截图配置脚本:rasterize.js,至于PhantomJS,大家就自行去官网下载吧。
转载请注明原址:/article/5813055.html
相关文章推荐
- [杂]EXTJS 浅谈及开发过程中的理解
- JavaScript之对象继承顺序
- JVM性能调优监控工具jps、jstack、jmap、jhat、jstat使用详解
- 当页面完全加载完成后执行一个js函数
- zepto.js 实现原理解析
- 于 jsp第横梁list数据
- Hello JSP!——JSP内置对象分类及属性保存范围
- JSTL标签 参考手册
- BZOJ 1028: [JSOI2007]麻将 暴力
- boost property tree 解析Json ini
- extjs关于treePanel+chekBox全部选中以及清空选中问题探讨
- gulp打包seajs,用gulp-cmd-pack打包seajs模块
- jsp页面出现end tag "</c:forEach" is unbalanced
- A JavaScript Image Gallery
- Ext js学习笔记(二) 表格的创建
- Extjs 学习(一) 选择器
- JS实现动画
- extjs中treepanel例子
- JavaScript语言精粹 笔记06 方法
- JSP学习