使用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 相关文章推荐
javascript引导程序
Oct 26 Javascript
基于JQuery实现的图片自动进行缩放和裁剪处理
Jan 31 Javascript
JavaScript将取代AppleScript?
Sep 18 Javascript
javascript实现当前页导航激活的方法
Feb 27 Javascript
常常会用到的截取字符串substr()、substring()、slice()方法详解
Dec 16 Javascript
javascript实现表单验证
Jan 29 Javascript
jQuery基于扩展实现的倒计时效果
May 14 Javascript
使用jQuery5分钟快速搞定双色表格的简单实例
Aug 08 Javascript
jquery 实现复选框的全选操作实例代码
Jan 24 Javascript
ES6知识点整理之Proxy的应用实例详解
Apr 16 Javascript
jquery轮播图插件使用方法详解
Jul 31 jQuery
浅谈vue中使用编辑器vue-quill-editor踩过的坑
Aug 03 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
雄兵连三大错觉:凯莎没了,凉冰阵亡了,华烨觉得自己又行了
2020/04/09 国漫
PHP 字符串操作入门教程
2006/12/06 PHP
PHP笔记之:基于面向对象设计的详解
2013/05/14 PHP
PHP中file_exists()判断中文文件名无效的解决方法
2014/11/12 PHP
PHP 微信支付类 demo
2015/11/30 PHP
为何说PHP引用是个坑,要慎用
2018/04/02 PHP
HTML5如何适配 iPhone IOS 底部黑条
2021/03/09 HTML / CSS
再次更新!MSClass (Class Of Marquee Scroll通用不间断滚动JS封装类 Ver 1.6)
2007/02/05 Javascript
JS小框架 fly javascript framework
2009/11/26 Javascript
javascript管中窥豹 形参与实参浅析
2011/12/17 Javascript
jquery $("#variable") 循环改变variable的值示例
2014/02/23 Javascript
javascript实现ecshop搜索框键盘上下键切换控制
2015/03/18 Javascript
整理关于Bootstrap过渡动画的慕课笔记
2017/03/29 Javascript
js获取浏览器的各种属性
2017/04/27 Javascript
JSON 数据格式详解
2017/09/13 Javascript
jQueryMobile之窗体长内容的缺陷与解决方法实例分析
2017/09/20 jQuery
js常用正则表达式集锦
2019/05/17 Javascript
微信小程序getLocation 需要在app.json中声明permission字段
2020/03/03 Javascript
python matplotlib绘图,修改坐标轴刻度为文字的实例
2018/05/25 Python
Python彻底删除文件夹及其子文件方式
2019/12/23 Python
Python ellipsis 的用法详解
2020/11/20 Python
详解使用scrapy进行模拟登陆三种方式
2021/02/21 Python
Keds官方网站:购买帆布运动鞋和经典皮鞋
2016/11/12 全球购物
英国天然宝石首饰购买网站:Gemondo Jewellery
2018/10/23 全球购物
FC-Moto西班牙:摩托车手最大的购物场所之一
2019/04/11 全球购物
可以使用抽象函数重写基类中的虚函数吗
2013/06/02 面试题
业务主管岗位职责
2013/11/20 职场文书
施工员岗位职责
2014/03/16 职场文书
某集团股份有限公司委托书样本
2014/09/24 职场文书
导师鉴定意见
2015/06/05 职场文书
初中开学典礼新闻稿
2015/07/17 职场文书
农贸批发市场管理制度
2015/08/07 职场文书
南阳市白酒市场的调查报告
2019/11/08 职场文书
导游词之天津古文化街
2019/11/09 职场文书
一看就懂的MySQL的聚簇索引及聚簇索引是如何长高的
2021/05/25 MySQL
vue二维数组循环嵌套方式 循环数组、循环嵌套数组
2022/04/24 Vue.js