使用Phantomjs和Node完成网页的截屏快照的方法


Posted in Javascript onJuly 16, 2019

由于甲方爸爸的需要,最近使用phantomjs和Node写了一个对网页内容截屏的功能,为了避免忘记,现在将代码内容及配置流程大概描述一下.

1.首先Node是必须安装的,而且网上安装教程一大堆,在此不再赘述,Nodejs官网链接

2.然后,第二个主人公是phantomjs,官网下载地址,选择对应的系统下载对应的安装包

3.将phantomjs配置为系统变量,下面是Windows配置为环境变量:

使用Phantomjs和Node完成网页的截屏快照的方法

配置完成之后,在cmd命令行中输入 phantomjs -v 检验是否配置成功,配置成功之后,如下图所示:

使用Phantomjs和Node完成网页的截屏快照的方法

4.撸代码,通过查阅phantomjs入门代码之后,了解到使用phantomjs可以预览一个网页生成图片,PDF,base64格式等等,而我们的项目需要的并不是一个完整的网页,而是网页中的一部分内容,所以在此基础之上要改造部门内容,现在讲解一下代码:

4.1)首先是express的一些设置,由于需要执行phantomjs的命令,所以需要引入child_process模块,具体代码如下:

var process = require('child_process');//执行命令行所需
var express = require('express');//express
var bodyParser = require('body-parser');
var fs = require("fs");//文件操作
var app = express();
 
app.use('/pages',express.static('pdfs'));//设置静态资源目录
app.use(bodyParser.json({limit:'50mb'}));//请求内容大小限制
app.use(bodyParser.urlencoded({limit:'50mb',extended:false})); 
 
//设置允许跨域访问
var allowCrossDomain = function(req, res, next) {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
  res.header('Access-Control-Allow-Headers', 'Content-Type');
  res.header('Access-Control-Allow-Credentials','true');
  next();
};
 
app.use(allowCrossDomain);

4.2)然后就是生成页面的base64接口的方法,如下:

app.get('/getBase64',function(req,res){
	var url=req.query.url;//读取请求中的url参数,然后访问这个url
  url=url.replace(/&/g,'%26');//将请求中的&转换 
	var resp={
	  "status":'200'
	}
	res.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});//设置响应头
	if(url==''){
    resp.msg='url参数不能为空';
    res.end(JSON.stringify(resp));  
	}
	else{
    //phantomjs执行的命令行 index.js在后文中给出
		var strShell='phantomjs --disk-cache=true --disk-cache-path=. index.js '+url;
    process.exec(strShell,{
    	maxBuffer:5000*1024,
    },function(error,stdout,strerr){
    	if(error!==null){
        console.log(error);
    		resp.msg='转换失败,稍后重试';
    		res.end(JSON.stringify(resp));
    	}else{
        //执行成功则返回base64的数据
    		resp.data=stdout;
    		res.end(JSON.stringify(resp));
    	}
    })
	}
 
})

4.3)phantomjs执行的脚本,即index.js,如下:

var page = require('webpage').create();//获取webpage
var system = require('system'),
  address;
 
if (system.args.length === 1) {//执行的命令应该包括请求的URL,否则退出phantom
  console.log('Usage: URL error');
  phantom.exit();
}
address = system.args[1];//请求的地址
address = address.replace(/%26/g, '&');//phantom不能识别%26,所以转为&
page.viewportSize = {//设置viewport
  width: 1920,
  height: 1080,
}
page.open(address, function(status) {//打开页面
  setTimeout(function() {//2s之后获取base64结果,如果直接生成有可能页面还没有加载完成
    if (status == 'success') {
      var base64 = page.renderBase64('PNG');
      console.log(base64);//将base64结果输出之后,在上边的getBase64接口中获取
      phantom.exit();
    }
  }, 2000);
})

4.4)获取页面中部分内容的截图,可以将需要截图的DOM字符串,发送至后台,然后新建一个空的页面,使用phantom访问该空白页面,并将DOM字符串添加到预览的页面,然后生成截图,具体代码如下:

app.post('/getPartPage', function(req, res) {
  var xmlObj = req.body.xmlObj;//获取DOM字符串
  const reqUrl = 'http:example.com/tmp.html';//要访问的空页面
  var response = {
    "status": '200',
  };
  if (xmlObj == undefined || xmlObj == '' || xmlObj == null) {
    response.msg = 'DOM字符串内容未输入';
    res.end(JSON.stringify(response));
  }else {
    fs.writeFile('tmp.txt', xmlObj, function(err) { //由于dom字符串内容过多,所以写入txt文本
      if (err) {
        response.msg = '生成页面失败,请稍后重试';
        return res.end(JSON.stringify(response));
      }
 
      var strShell = 'phantomjs pages/index.js ' + reqUrl;//phantomjs执行的命令
      process.exec(strShell, {
        maxBuffer: 5000 * 1024,
      }, function(error, stdout, strerr) {
        if (error !== null) {
          response.msg = '脚本执行错误,请稍后重试';
          res.end(JSON.stringify(response));
        } else {
          response.data = stdout.replace("\r\n", "");
          res.end(JSON.stringify(response));//返回结果
        }
 
      })
 
    })
 
  }
 
})
 
var server = app.listen(8808,function(){ //接口监听,访问的端口
	var host = server.address().address
	var port = server.address().port
  console.log('http://%s:%s',host,port);
})

4.5)pages下的index.js内容如下所示:

var page = require('webpage').create();//获取webpage
var fs = require('fs');
var system = require('system'),
  address,filename;
 
if (system.args.length === 1) {
  console.log('Usage: URL error');
  phantom.exit();
}
address = system.args[1];//请求的路径
address = address.replace(/%26/g, '&');
filename = (new Data()).getTime();
page.viewportSize = {
  width: 750,
}
page.paperSize = { //生成A4大小的PDF文件
  format: 'A4',
  orientation: 'portrait',
  margin: '0.8cm'
}
page.open(address, function(status) {
  var info = fs.read('tmp.txt');//读取DOM字符串
  var result = page.evaluate(function(info) {
    try {
      document.querySelector('#dom').innerHTML = info;//将dom字符串拼接
    } catch (e) {
      console.log(e);
    }
 
    return document.querySelector('#dom').innerHTML;//返回页面
  }, info);
  setTimeout(function() {
    page.paperSize = {
      format: 'A4',
      orientation: 'portrait',
      margin: '0.8cm'
    };
    page.viewportSize = {
      width: 750,
    };
    //生成PDF文件 
    page.render('pages/' + filename + '.pdf', { format: 'pdf', quality: '100' });
    console.log('http://example.com/pages/' + filename + '.pdf');//返回PDF文件的访问路径
    phantom.exit();
  }, 500);
})

OK,以上就是全部接口的内容,全部的代码可以访问https://github.com/kim095/node-phantom进行下载.希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
再谈ie和firefox下的document.all属性
Oct 21 Javascript
js实现的点击div区域外隐藏div区域
Jun 30 Javascript
js控制再次点击按钮之间的间隔时间可防止重复提交
Aug 01 Javascript
使用Web Uploader实现多文件上传
Jun 08 Javascript
AngularJS中$apply方法和$watch方法用法总结
Dec 13 Javascript
Angular-Ui-Router+ocLazyLoad动态加载脚本示例
Mar 02 Javascript
vue分类筛选filter方法简单实例
Mar 30 Javascript
jQuery插件select2利用ajax高效查询大数据列表(可搜索、可分页)
May 19 jQuery
Angular4如何自定义首屏的加载动画详解
Jul 26 Javascript
vue打包之后生成一个配置文件修改接口的方法
Dec 09 Javascript
Vuex 模块化使用详解
Jul 31 Javascript
vue 集成jTopo 处理方法
Aug 07 Javascript
详解微信小程序支付流程与梳理
Jul 16 #Javascript
如何在项目中使用log4.js的方法步骤
Jul 16 #Javascript
JAVA面试题 static关键字详解
Jul 16 #Javascript
微信小程序实现下拉框功能
Jul 16 #Javascript
javascript中的this作用域详解
Jul 15 #Javascript
微信小程序页面上下滚动效果
Nov 18 #Javascript
node.js实现上传文件功能
Jul 15 #Javascript
You might like
如何冲泡挂耳包咖啡?技巧是什么
2021/03/04 冲泡冲煮
PHP-redis中文文档介绍
2013/02/07 PHP
解析如何通过PHP函数获取当前运行的环境 来进行判断执行逻辑(小技巧)
2013/06/25 PHP
php多文件上传实现代码
2014/02/20 PHP
跟我学Laravel之安装Laravel
2014/10/15 PHP
PHP curl 或 file_get_contents 获取需要授权页面的方法
2017/05/05 PHP
解决php用mysql方式连接数据库出现Deprecated报错问题
2019/12/25 PHP
JavaScript中的稀疏数组与密集数组[译]
2012/09/17 Javascript
js拖动div 当鼠标移动时整个div也相应的移动
2013/11/21 Javascript
JS比较两个时间大小的简单示例代码
2013/12/20 Javascript
js检测输入内容全为空格的方法
2014/05/03 Javascript
JavaScript的各种常见函数定义方法
2014/09/16 Javascript
简介JavaScript中POSITIVE_INFINITY值的使用
2015/06/05 Javascript
jQuery插件formValidator自定义函数扩展功能实例详解
2015/11/25 Javascript
详解javascript new的运行机制
2016/01/26 Javascript
jQuery中的基本选择器用法学习教程
2016/04/14 Javascript
JavaScript重载函数实例剖析
2016/05/13 Javascript
JavaScript SHA1加密算法实现详细代码
2016/10/06 Javascript
微信小程序 input输入框详解及简单实例
2017/01/10 Javascript
ES6中的箭头函数实例详解
2017/04/06 Javascript
js canvas实现简单的图像扩散效果
2020/06/28 Javascript
解决vue组件中使用v-for出现告警问题及v for指令介绍
2017/11/11 Javascript
除Console.log()外更多的Javascript调试命令
2018/01/24 Javascript
vue进行图片的预加载watch用法实例讲解
2018/02/07 Javascript
vue实现element-ui对话框可拖拽功能
2018/08/17 Javascript
koa2使用ejs和nunjucks作为模板引擎的使用
2018/11/27 Javascript
使用Python微信库itchat获得好友和群组已撤回的消息
2018/06/24 Python
Python查找第n个子串的技巧分享
2018/06/27 Python
python统计字母、空格、数字等字符个数的实例
2018/06/29 Python
浅谈tensorflow中张量的提取值和赋值
2020/01/19 Python
解决TensorFlow GPU版出现OOM错误的问题
2020/02/03 Python
全球烹饪课程的领先预订平台:Cookly
2020/01/28 全球购物
会计职业生涯规划书
2014/01/13 职场文书
《燕子专列》教学反思
2014/02/21 职场文书
群众路线教育实践活动思想汇报(2014特荐篇)
2014/09/16 职场文书
关于Javascript闭包与应用的详解
2021/04/22 Javascript