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

    CSS常用样式 10.自定义动画 1)关键帧(keyframes) 被称为关键帧,其类似于Flash中的关键帧. 在CSS3中其主要以“@keyframes”开头,后面紧跟着是动画名称加上一对花括号“ ...

  2. SHA-1算法

    SHA-1.h #ifndef _SHA1_H #define _SHA1_H #include<iostream> using namespace std; //4个函数 #define ...

  3. arcgis api for js入门开发系列七图层控制(含源代码)

    上一篇实现了demo的地图分屏对比模块,本篇新增图层控制模块,截图如下(源代码见文章底部): 图层控制模块实现的思路如下: 1.在地图配置文件map.config.js里面配置图层目录树节点信息,作为 ...

  4. Linux基础介绍【第七篇】

    linux用户分类 超级用户:UID=0,root 普通用户:UID 500起,由超级用户或具有超级用户权限的用户创建的用户. 虚拟用户:UID 1-499,为了满足文件或服务启动的需要而存在,一般都 ...

  5. Unity3D新手引导开发手记

    最近开始接手新手引导的开发,记录下这块相关的心得 首先客户端是Unity,在接手前,前面的同学已经初步完成了新手引导框架的搭建,这套框架比较简单,有优点也有缺点,稍后一一点评 我们的新手引导是由一个个 ...

  6. Android点击列表后弹出输入框,所点击项自动滚动到输入框上方

    使用微信的朋友圈会发现,点击某一条评论后输入框会弹出来,然后所点击的那一项会自动地滚动到输入框上方的位置,这样如果开始所点击的评论在屏幕很下方的话,就不会被输入框遮住,虽然微信这一点在我的MX2频繁点 ...

  7. ABP(现代ASP.NET样板开发框架)系列之1、ABP总体介绍

    点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之1.ABP总体介绍 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)” ...

  8. 使用nwjs开发桌面应用之Hello,World!

    今天发现原来JavaScript也可以用来开发桌面应用程序,顿时有一种很牛逼的感觉,于是马上就开始了Hello,World!,感受一下JavaScript的强大. 可以用来开发桌面应用的js框架有三种 ...

  9. 新项目的CQRS设计

    刚换了个工作,闲话不说了.前两天开始一个新项目,大概是一个任务管理系统,由使用者来选取任务,执行任务,反馈完成,我大概做了些设计,本来是打算看能不能在新公司铺垫一下DDD,不过后来这块功能没分到我这, ...

  10. Python标准模块--import

    1 模块简介 作为一个Python初学者,你首先要学会的知识就是如何引入其它模块或者包.但是,我发现有些开发者虽然使用Python很多年,依然不了解Python引入机制的灵活性.这篇文章,我们就会研究 ...