使用puppeteer 进行批量网页截图
数据来源为一个txt文件
每一行用\t分割后 前面是域名后面是url 域名用来md5后作为截图名
pageSize控制一次最多打开多少个页面 防止网页过多占用内存过多
配置里的'--proxy-server=socks5://127.0.0.1:1080' 是用来走本地小飞机代理的
const puppeteer = require('puppeteer');
var fs = require('fs');
var readline = require('readline');
const crypto = require('crypto');
var file = '/test/snap.txt';
//最多多少个页面
const pageSize = 50;
var date = new Date();
var startTime = date.getTime();
readFileToArr(file ,async function (data){console.log('本次需要截图[' + data.length+']条')console.log('开始执行:'+startTime);if(data.length>0){snp(data).then(() => {console.log('执行清空文件操作');fs.access(file, fs.constants.F_OK, (err) => {console.log(`${file} ${err ? '不存在' : '存在'}`);var ws1 = fs.createWriteStream(file, 'utf-8');ws1.write('');ws1.end();console.log(`${file}` +' 已清空');});}).catch(function (err) {console.log(err);});;}
});async function snp(arr){const config = {ignoreHTTPSErrors:true,defaultViewport:{width:1920,height:1080},args: ['--no-sandbox','--proxy-server=socks5://127.0.0.1:1080'],headless: true}const browser = await puppeteer.launch(config);var that = this;while(arr.length>0){var some;if(arr.length >pageSize){some = arr.splice(0,pageSize);}else{some = arr.splice(0,arr.length);}var length = some.length;var a = [];for (let j = 0; j < length; j++) {if(some[j] === '') continue;var line = some[j].split('\t');if(line.length !==2 ){console.log('数据不全:' + some[j]);continue;}var domain = line[0];var url = line[1];var page = await browser.newPage();//默认30S超时//page.setDefaultNavigationTimeout(3000);try{await page.goto(url);console.log('已打开:'+url);page.on('dialog', async dialog => {await dialog.accept();});}catch(err){console.log('打开网页出错:'+err);}a.push(page);}//等待时间 可调整//await a[0].waitFor(1 * 1000);for (i = 0; i < length; i++) {if(some[i] === '') continue;var line = some[i].split('\t');if(line.length !==2 ){console.log('数据不全:' + some[i]);continue;}var domain = line[0];var url = line[1];var fileName = getMD5(domain) + '.png';try {await a[i].screenshot({ path: '/test/snapshot/'+fileName });console.log('截图成功: '+domain);await a[i].close();} catch (e) {console.log('截图出错: '+e)}}}await browser.close();var endTime = new Date().getTime();console.log('执行结束:'+endTime);console.log('本次执行时间:' + (endTime-startTime)/1000 + 's');
}//读取文件
function readFileToArr(fReadName,callback){var fRead = fs.createReadStream(fReadName);var objReadline = readline.createInterface({input:fRead});var arr = new Array();objReadline.on('line',function (line) {arr.push(line);//console.log('line:'+ line);});objReadline.on('close',function () {// console.log(arr);callback(arr);});
}
//获取md5值
function getMD5(data) {// 加入字符编码var md5 = crypto.createHash('md5').update(data, 'utf-8').digest('hex');return md5;
}
目前还可以优化的地方:
当前流程是依次打开网页,等待当前网页加载完成后再去打开下一个网页,若某一个网页打开较慢或打不开,则会一直等待到超时。
可以改为调用goto后不等待,并行的打开网页,大大减少打开网页过程中花费的时间。
第二版
由于第一版 虽说是一次打开多个标签页了,但是实质上还是和串行一个个打开没有区别,我在page的load事件上也没有找到能保存当前页面上下文并使其在后面可选择使用的好办法。
所以不如直接使用串行 由于截图任务要的是准确第一 速度第二 所以改为串行也未尝不可
主要改动的地方就是snp()方法 并且删掉了pageSize这个常量
async function snp(arr){const config = {ignoreHTTPSErrors:true,defaultViewport:{width:1920,height:1080},args: ['--no-sandbox','--start-maximized'],headless: false}const browser = await puppeteer.launch(config);var page = await browser.newPage();for(let i=0;i<arr.length;i++){if(arr[i] === '') continue;var line = arr[i].split('\t');if(line.length !==2 ){console.log('数据不全:' + arr[i]);continue;}var domain = line[0];var url = line[1];var fileName = getMD5(domain) + '.png';await page.goto(url,{waitUntil: ['networkidle0']}).then(()=>{console.log('已打开:'+url);}).catch( err =>{console.log('打开网页出错:' + url);});page.on('dialog', async dialog => {await dialog.accept();});await page.screenshot({path: '/Users/rzx/Desktop/snapshot/'+fileName});console.log('截图成功: '+domain);}await page.close();await browser.close();var endTime = new Date().getTime();console.log('本次执行时间:' + (endTime-startTime)/1000 + 's');
}
- 为什么使用--start-maximized这个参数:有些网页在最大化下和它默认大小下 截出来的图片不一样 默认尺寸下可能会出现拼接的情况
- await page.goto(url,{waitUntil: ['networkidle0']}) 此处waitUntil的作用:有些网页 打开后会继续请求js 做出动画或改变样式 添加此参数的意思是直到没有任何网络连接 视为跳转成功。可以有效避免部分网页刚打开 load事件触发了就截图 截出的图不完整
使用puppeteer 进行批量网页截图相关推荐
- 用selenium在python下实现批量网页 截图
需要用到的工具是selenium, 引用下百度的解释: Selenium [1] 是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包 ...
- 有了 serverless,前端也可以快速开发一个 Puppeteer 网页截图服务
更多云原生技术资讯可关注阿里巴巴云原生技术圈. Puppeteer 是什么? puppeteer 官网的介绍如下: Puppeteer is a Node library which provides ...
- Serverless 实战 —— 前端也可以快速开发一个 Puppeteer 网页截图服务
Serverless 实战 -- 前端也可以快速开发一个 Puppeteer 网页截图服务 更多云原生技术资讯可关注阿里巴巴云原生技术圈. Puppeteer 是什么? puppeteer 官网的介绍 ...
- 通过网址自动网页截图(Selenium实现)
在自动化测试或者想要批量获取网页首页图片时,就需要一个脚本实现自动化网页截图,我们可以通过Selenium实现这个功能. 1. 安装Selenium pip install selenium 2. ...
- C#实现网页截图功能
//需要添加System.Drawing及System.Windows.Forms引用 using System; using System.Drawing; using System.Drawing ...
- [IE9] 解决了傲游、搜狗浏览器在IE9下网页截图的问题
因为IE9直接使用硬件图形接口D2D/DWrite进行网页渲染,所以使用基于GDI的函数访问IE9的时候会出现问题. 目前国内的浏览器(如:傲游,搜狗)都是使用GDI函数来实现网页截图的, 当IE内核 ...
- html2canvas 截图div_浏览器端网页截图方案详解
简介 剖析流行的截图插件 html2canvas 的实现方案,探索其功能上的一些不足之处及不能正确截取的一些场景,比如不支持 CSS 的 box-shadow 截取情况等.探索一种新的实现方式,能够避 ...
- 网页截图工具CutyCapt
网页截图工具CutyCapt CuteCapt是Kali Linux提供的一款网页截图工具.该工具运行在命令行中,可以将WebKit引擎解析的网页保存为图片.它保存的文件支持矢量图和位图两大类型,共1 ...
- react骨架屏自动生成_用纯 DOM 的方式结合 Puppeteer 自动生成网页骨架屏
骨架屏是在页面数据尚未加载完成前先给用户展示出页面的大致结构,直到请求数据返回后再显示真正的页面内容:随着单页应用( SPA )的越来越流行,单页应用的用户体验也越来越得到前端开发者的关注:为了优化用 ...
最新文章
- Chrome 浏览器调试移动端
- AIX忘记root密码后,重设密码步骤
- 安大计算机学院院长汤进,淮北师范大学
- 深度学习 2 机器学习 神经网络 卷积神经网络
- 【图像分割】基于matalb灰狼算法最小交叉熵多阈值图像分割【含Matlab源码 903期】
- OpenJudge NOI题库 入门 116题 (一)
- SSH智能社区住户信息管理系统
- 云时代数据容灾的正确姿势
- PDF怎么打印?为什么有时选择打印没有反应?
- JS基础——图片切换的综合实例
- 某网站cookie加密黑盒调用与算法还原
- phpcms下载页直接显示下载真实地址方法
- 谈谈市场上常用语音芯片方案选型,录音芯片方案选型
- 高级去雾算法与原理--暗原色图技术
- 我是如何入行嵌入式开发的
- Excel如何批量重命名文件
- 64位系统的Detours
- php中判断是否为偶数,在PHP中检查偶数和奇数
- 【技巧】只改变word背景颜色,并保持其他软件背景颜色不变
- 硬件原理图Checklist检查表(通用版)
热门文章
- 【Vision主网】申请及部署第一验证者FV节点全流程
- git 常用操作总结——基于Gitlab
- 暴强贴:从.NET平台调用Win32 API
- 通过Anaconda安装Python时安装路径错误,提示XX is not empty ,please choose a different location.问题的解决方案
- 【工具配置】CLion编译c语言的配置
- 软件工程SSM毕设中药店商城系统(含源码+论文)
- 经纬度转凯立德 K 码
- 润乾报表打印html,润乾报表纯文本打印的实现
- 计算机桌面有去不掉的框,电脑屏幕有残留刷新去不掉怎么办
- python二元函数求导_tensorflow的函数自动求导是如何实现的?