利用java实现一个网页的滚动截图,实现中无需打开浏览器。基于phantomjs 和rasterize.js实现。
补充说明:phantomjs-2.1.1-windows对react开发的页面会存在页面组件错乱的问题,可以下载phantomjs-2.5.0-beta2-windows版本进行截图,但是phantomjs-2.5.0-beta2-windows这个版本对vue开发的页面截图不成功,目前不明白原因。综上所述:phantomjs-2.1.1-windows:支持vue开发的页面,react开发的页面会出现组件错乱问题
phantomjs-2.5.0-beta2-windows:支持react开发的页面,不会出现组件错乱的问题,对vue开发的页面可能截图不成功
PhantomJS是一个基于webkit的javaScript API。它使用QtWebKit作为它核心浏览器的功能,使用webkit来编译解释执行javaScript代码。任何你可以基于在webkit浏览器做的事情,它都能做到。它不仅是个隐性的浏览器,提供了诸如css选择器、支持wen标准、DOM操作、json、HTML5等,同时也提供了处理文件I/O的操作,从而使你可以向操作系统读写文件等。phantomJS的用处可谓非常广泛诸如网络监测、网页截屏、无需浏览器的wen测试、页面访问自动化等。
截图脚本:rasterize.js
所需环境:D:\phantomjs-2.1.1-windows\bin\phantomjs.exe
将rasterize.js也放在统计目录
可以通过cmd 测试所需环境是否有效。在你的制定目录是否有生成的图片
上代码:
项目基于Springboot开发
controller:
@Resource
private CutPictureService cutPictureService;
@GetMapping("/getcutPictureInfo")
public Result cutPicture(String url) {
Result result = new Result("cutPicture_ACK", TipsMessage.FAILED_CODE);
if (ParamUtil.isOneEmpty(url)) {
result.setCode(TipsMessage.PARAM_ERROR_CODE);
return result;
}
CommonResult.Instance.getResult(cutPictureService.cutPicture(url), result);
return result;
}
service:
private static final String _shellCommand1 = "D:/phantomjs-2.1.1-windows/bin/phantomjs";
private static final String _shellCommand2 = "D:/phantomjs-2.1.1-windows/bin/rasterize.js";
@Override
public boolean cutPicture(String url) {
boolean info = false;
try {
info = getByteImg(url);
} catch (IOException e) {
e.printStackTrace();
}
return info;
}
private String _file;
private String _size;
/**
* 将目标网页转为图片字节流
*
* @param url 目标网页地址
* @return 字节流
*/
public boolean getByteImg(String url) throws IOException {
String _file = "C:/"+ UUIDUtil.getUUID()+".png";
BufferedInputStream in = null;
boolean flag = exeCmd(_shellCommand1 + " " + _shellCommand2 +" " + url + " " + _file);
return flag;
}
/**
* 执行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) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
return true;
}
结果:
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: 800, height: 200 };
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 };
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 * 9/16, 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);
}
});
}
PhantomJS 可以自己在网上下载