关于PhantomJS
PhantomJS 是一个基于WebKit的服务器端 JavaScript API。它全面支持web而不需浏览器支持,其快速,原生支持各种Web标准: DOM 处理, CSS 选择器, JSON, Canvas, 和 SVG。PhantomJS可以用于页面自动化,网络监测,网页截屏,以及无界面测试等。
我们还可以用它来做爬虫哦,大家知道,网页上有些数据是通过执行js渲染出来的,这样的话爬虫去抓取数据的时候就会很麻烦,PhantomJS自带WebKit内核,我们可以利用PhantomJS解决爬虫不能执行js的问题。
这次要说的是他的截图功能
下面是官网提供的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: 600, height: 600 }; ???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 }; ???????????// 通过clipRect可以指定渲染的区域: ???????????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 * 3/4, 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); ???????} ???});}
上面的代码可以进行截图,不过问题就在于,页面的高度需要我们手动指定,那就不方便了。
在园子里发现有个哥们通过手动设定高度的方法来解决这个问题:http://www.cnblogs.com/xiehuiqi220/p/3551699.html,不过页面的高度没有那么高,渲染的图片下面就会出现大块的留白,也是不够灵活。
想到PhantomJS本身也可以执行js的,我们可以将页面加载完毕后,获取页面的实际高度,然后重新设定截取的区域,不就可以解决了。
于是便有了以下代码:
// 通过在页面上执行脚本获取页面的渲染高度var bb = page.evaluate(function () { ??return document.getElementsByTagName(‘html‘)[0].getBoundingClientRect(); });// 按照实际页面的高度,设定渲染的宽高page.clipRect = { ?top: ???bb.top, ?left: ??bb.left, ?width: ?bb.width, ?height: bb.height};// 预留一定的渲染时间window.setTimeout(function () { ?page.render(file); ?page.close(); ?console.log(‘render ok‘);}, 1000);
改造后的代码如下:
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‘); ???phantom.exit(1);} else { ???address = system.args[1]; ???output = system.args[2]; ???page.viewportSize = { width: 1024, height: 600 }; ???page.open(address, function (status) { ?????// 通过在页面上执行脚本获取页面的渲染高度 ?????var bb = page.evaluate(function () { ????????return document.getElementsByTagName(‘html‘)[0].getBoundingClientRect(); ??????}); ?????// 按照实际页面的高度,设定渲染的宽高 ?????page.clipRect = { ???????top: ???bb.top, ???????left: ??bb.left, ???????width: ?bb.width, ???????height: bb.height ?????}; ?????// 预留一定的渲染时间 ?????window.setTimeout(function () { ???????page.render(output); ???????page.close(); ???????console.log(‘render ok‘); ?????}, 1000); ???});}
通过执行D:\Software\phantomjs-1.9.7-windows>phantomjs.exe render.js http://cnblogs.com cnblogs.png
就可以把博客园首页截取下来了。
效果如下:
网页html截屏转图片(二)PhantomJS
原文地址:https://www.cnblogs.com/lixiaoran/p/10800207.html