使用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 相关文章推荐
JQuery 遮罩层实现(mask)实现代码
Jan 09 Javascript
JavaScript 字符串处理函数使用小结
Dec 02 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(五)可移动地图的实现
Jan 23 Javascript
如何在JavaScript中实现私有属性的写类方式(一)
Dec 04 Javascript
Jqgrid表格随窗口大小改变而改变的简单实例
Dec 28 Javascript
js时间比较示例分享(日期比较)
Mar 05 Javascript
Jquery给基本控件的取值、赋值示例
May 23 Javascript
js创建一个input数组并绑定click事件的方法
Jun 12 Javascript
javascript跨域的方法汇总
Oct 23 Javascript
jQuery组件easyui对话框实现代码
Aug 25 Javascript
vue 项目如何引入微信sdk接口的方法
Dec 18 Javascript
jQuery使用ajax传递json对象到服务端及contentType的用法示例
Mar 12 jQuery
详解微信小程序支付流程与梳理
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
Admin generator, filters and I18n
2011/10/06 PHP
深入解析phpCB批量转换的代码示例
2013/06/27 PHP
zf框架的校验器InArray使用示例
2014/03/13 PHP
Win7 64位系统下PHP连接Oracle数据库
2014/08/20 PHP
Smarty简单生成表单元素的方法示例
2016/05/23 PHP
在IE上直接编辑网页内容的js代码(IE地址栏js)
2009/04/27 Javascript
JavaScript 浏览器对象模型BOM使用介绍
2015/04/13 Javascript
Jquery简单分页实现方法
2015/07/24 Javascript
jQuery实现自动切换播放的经典滑动门效果
2015/09/12 Javascript
JS获取input file绝对路径的方法(推荐)
2016/08/02 Javascript
Vue实现动态添加或者删除对象和对象数组的操作方法
2018/09/21 Javascript
微信小程序五子棋游戏的棋盘,重置,对弈实现方法【附demo源码下载】
2019/02/20 Javascript
基于ssm框架实现layui分页效果
2019/07/27 Javascript
js获取 gif 的帧数的代码实例
2019/09/10 Javascript
[48:56]2018DOTA2亚洲邀请赛 3.31 小组赛 A组 VG vs KG
2018/03/31 DOTA
[26:52]LGD vs EG 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
Python的内存泄漏及gc模块的使用分析
2014/07/16 Python
Python Sleep休眠函数使用简单实例
2015/02/02 Python
python中数据爬虫requests库使用方法详解
2018/02/11 Python
python使用tensorflow深度学习识别验证码
2018/04/03 Python
python爬虫之线程池和进程池功能与用法详解
2018/08/02 Python
Python 正则表达式匹配字符串中的http链接方法
2018/12/25 Python
华为2019校招笔试题之处理字符串(python版)
2019/06/25 Python
如何让PyQt5中QWebEngineView与JavaScript交互
2020/10/21 Python
Python3中FuzzyWuzzy库实例用法
2020/11/18 Python
数据库专业英语
2012/11/30 面试题
股权转让协议书范本
2014/04/12 职场文书
公路绿化方案
2014/05/12 职场文书
房地产开发项目建议书
2014/05/16 职场文书
机械设计及其自动化专业求职信
2014/06/09 职场文书
乡镇党建工作汇报材料
2014/08/14 职场文书
门卫岗位职责说明书
2014/08/18 职场文书
镇党委书记群众路线整改措施思想汇报
2014/10/13 职场文书
2014年政务公开工作总结
2014/12/09 职场文书
小学教师岗位职责
2015/04/02 职场文书
2015年推普周活动方案
2015/05/06 职场文书