这是上半年遇到的一个小需求,想实现网页的抓取,并保存为图片。研究了不少工具,效果都不理想,不是显示太差了(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

截图的脚本在官网上有提供,但是我这里需要说明一下它的高宽度设计原理:

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,大家就自行去官网下载吧。

转载请注明原址:http://www.cnblogs.com/lekko/p/4796062.html  

使用PhantomJS实现网页截图服务的更多相关文章

  1. 有了 serverless,前端也可以快速开发一个 Puppeteer 网页截图服务

    更多云原生技术资讯可关注阿里巴巴云原生技术圈. Puppeteer 是什么? puppeteer 官网的介绍如下: Puppeteer is a Node library which provides ...

  2. selenium网页截图和截图定位(无界面)phantomjs

    phantomjs是一款软件,需要重新安装. 参考: https://blog.csdn.net/liyahui_3163/article/details/79064108 案例代码: from se ...

  3. 利用PhantomJS进行网页截屏

    利用PhantomJS进行网页截屏 关于PhantomJS PhantomJS 是一个基于WebKit的服务器端 JavaScript API.它全面支持web而不需浏览器支持,其快速,原生支持各种W ...

  4. php结合phantomjs实现网页截屏、抓取js渲染的页面

    首先PhantomJS快速入门 PhantomJS是一个基于 WebKit 的服务器端 JavaScript API.它全面支持web而不需浏览器支持,其快速,原生支持各种Web标准: DOM 处理, ...

  5. 通过phantomjs 进行页面截图

    本文章参考了使用phantomjs操作DOM并对页面进行截图需要注意的几个问题 及phantomjs使用说明 这两篇文章,初次接触phantomjs的童鞋可以去看下这两篇原文 在学习中可以看下 pha ...

  6. java实现网页截图

    使用工具 java+selenium+phantomjs /chromedriver /firefox 1.分别是 phantomjs插件 google截图插件 和 firefox火狐浏览器截图插件2 ...

  7. C#使用phantomjs 进行网页整页截屏

    C#使用phantomjs 进行网页整页截屏 hantomjs 是一个基于js的webkit内核无头浏览器 也就是没有显示界面的浏览器,这样访问网页就省去了浏览器的界面绘制所消耗的系统资源,比较适合用 ...

  8. 如何将phantomjs单独部署在服务端

    如何将phantomjs单独部署在服务端 文章目录 一. 容我分析(lao dao)几句 二. 服务端 Look here 服务端phantomjs搭建 web端搭建及如何调用phantomjs 三. ...

  9. 利用PhantomJS搭建Highcharts export服务

    利用PhantomJS搭建Highcharts export服务 一直在使用Highcharts做web图表的展示, 但是当发送定时的报表邮件的遇到了这个问题. 为了保证邮件图表和web页图表样式一致 ...

随机推荐

  1. Git分布式版本控制教程

    Git分布式版本控制Git 安装配置Linux&Unix平台 Debian/Ubuntu $ apt-get install git Fedora $ ) $ dnf and later) G ...

  2. Tomcat常见问题及常用命令

    很长时间不用tomcat好多命令都忘记了,所以准备自己记录下来,以便参考.刚好也希望可以开始养成记博客的好习惯. 1.查看java的版本号 进入java的安装目录后,使用命令:java -versio ...

  3. EC笔记:第4部分:21、必须返回对象时,别返回引用

    使用应用可以大幅减少构造函数与析构函数的调用次数,但是引用不可以滥用. 如下: struct St { int a; }; St &func(){ St t; return t; } 在返回t ...

  4. ABP文档翻译--值对象

    本人是ABP初学者,在看英文文档和@tkb至简 的ABP框架理论研究总结(典藏版)时,发现大神@tkb至简中少了对Value Objects的翻译,看文档是新的,大神没时间把,小弟给补充上. 介绍 值 ...

  5. JQuery的基础和应用

    <参考文档>   1.什么是?    DOM的作用:提供了一种动态的操作HTML元素的方法.    jQuery是一个优秀的js库.用来操作HTML元素的工具.    jQuery和DOM ...

  6. Hibernate 系列 学习笔记 目录 (持续更新...)

    前言: 最近也在学习Hibernate,遇到的问题差不多都解决了,顺便把学习过程遇到的问题和查找的资料文档都整理了一下分享出来,也算是能帮助更多的朋友们了. 最开始使用的是经典的MyEclipse,后 ...

  7. angular中使用ngResource模块构建RESTful架构

    ngResource模块是angular专门为RESTful架构而设计的一个模块,它提供了'$resource'模块,$resource模块是基于$http的一个封装.下面来看看它的详细用法 1.引入 ...

  8. mono-3.4.0 源码安装时出现的问题 [do-install] Error 2 [install-pcl-targets] Error 1 解决方法

    Mono 3.4修复了很多bug,继续加强稳定性和性能(其实Mono 3.2.8 已经很稳定,性能也很好了),但是从http://download.mono-project.com/sources/m ...

  9. MyBatis4:动态SQL

    什么是动态SQL MyBatis的一个强大特性之一通常是它的动态SQL能力.如果你有使用JDBC或其他相似框架的经验,你就明白条件串联SQL字符串在一起是多么地痛苦,确保不能忘了空格或者在列表的最后的 ...

  10. ASP.NET Web API Model-ModelBinder

    ASP.NET Web API Model-ModelBinder 前言 本篇中会为大家介绍在ASP.NET Web API中ModelBinder的绑定原理以及涉及到的一些对象模型,还有简单的Mod ...