使用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 相关文章推荐
用正则xmlHttp实现的偷(转)
Jan 22 Javascript
Javascript Object.extend
May 18 Javascript
PHP使用方法重载实现动态创建属性的get和set方法
Nov 17 Javascript
JS实现的N多简单无缝滚动代码(包含图文效果)
Nov 06 Javascript
javascript发送短信验证码实现代码
Nov 12 Javascript
如何利用Promises编写更优雅的JavaScript代码
May 17 Javascript
js中利用cookie实现记住密码功能
Aug 20 Javascript
基于JavaScript实现弹幕特效
Aug 27 Javascript
jQuery中each循环的跳出和结束实例
Aug 16 jQuery
webpack dll打包重复问题优化的解决
Oct 10 Javascript
JS sort排序详细使用方法示例解析
Sep 27 Javascript
JavaScript实现复选框全选功能
Apr 11 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
PHP 图像尺寸调整代码
2010/05/26 PHP
Laravel5中contracts详解
2015/03/02 PHP
PHP可变变量学习小结
2015/11/29 PHP
php正则表达式基本知识与应用详解【经典教程】
2017/04/17 PHP
用js实现的模拟jquery的animate自定义动画(2.5K)
2010/07/20 Javascript
NodeJS框架Express的模板视图机制分析
2011/07/19 NodeJs
基于jquery的textarea发布框限制文字字数输入(添加中文识别)
2012/02/16 Javascript
JavaScript利用构造函数和原型的方式模拟C#类的功能
2014/03/06 Javascript
jquery实现预览提交的表单代码分享
2014/05/21 Javascript
微信小程序 两种滑动方式(横向滑动,竖向滑动)详细及实例代码
2017/01/13 Javascript
Vue0.1的过滤代码如何添加到Vue2.0直接使用
2017/08/23 Javascript
原生js实现简单的焦点图效果实例
2017/12/14 Javascript
简单理解Vue中的nextTick方法
2018/01/30 Javascript
vue项目实现github在线预览功能
2018/06/20 Javascript
JavaScript中的回调函数实例讲解
2019/01/27 Javascript
JavaScript动态创建二维数组的方法示例
2019/02/01 Javascript
webpack的pitching loader详解
2019/09/23 Javascript
Vue的Eslint配置文件eslintrc.js说明与规则介绍
2020/02/03 Javascript
vue实现图片按比例缩放问题操作
2020/08/11 Javascript
python字典多键值及重复键值的使用方法(详解)
2016/10/31 Python
Python程序退出方式小结
2017/12/09 Python
使用python实现ANN
2017/12/20 Python
Python装饰器用法实例总结
2018/02/07 Python
浅谈python3中input输入的使用
2019/08/02 Python
python django中8000端口被占用的解决
2019/12/17 Python
css3打造一款漂亮的卡哇伊按钮
2013/03/20 HTML / CSS
HTML5拖放功能_动力节点Java学院整理
2017/07/13 HTML / CSS
使用phonegap创建联系人的实现方法
2017/03/30 HTML / CSS
html5如何在Canvas中实现自定义路径动画示例
2017/09/18 HTML / CSS
法国设计制造的扫帚和刷子:Andrée Jardin
2018/12/06 全球购物
英语专业应届生求职信范文
2013/11/15 职场文书
暑期实习鉴定
2013/12/16 职场文书
2014年银行信贷员工作总结
2014/12/08 职场文书
2019思想汇报范文
2019/05/21 职场文书
教师节作文之小学四年级
2019/09/03 职场文书
漫画「古见同学有交流障碍症」第25卷封面公开
2022/03/21 日漫