dom截图——探究长截图的极限
长截图问题
问题:使用dom-to-image和html2canvas来进行长截图会出现一个问题,如果图片非常长,一些图片会只加载一半,如果图片再长一些,截图就会为空。
目前我测试的结果:截图的大小在8mb出现图片缺了的情况
截图为空不是库的bug,是浏览器到了极限,无法输出了,这时cpu飙到快100%。
图片缺失这个情况还可以优化,可以想办法把dom进行拆分,再分别截图,最后拼接图片
优化长截图的思路:
- 还是用js里的dom-to-image,不断拆分dom,分别截图,最后合并
- 使用selenium截图,滚动截图,再用opencv拼接图片
上面两个思路,是不是能实现无限长的截图呢?
方法一:按理说应该能无限长的,但是浏览器扛不住,我的测试结果是截图大小在18mb左右,再大一些就不输出了。
方法二:这个方法能实现无限长的截图,但太慢了
代码实现
方法一:推荐做法
核心思想:把如下图所示拆分的dom分别使用dom-to-image截图,再通过canvas合并图片,最后下载
要截图的完整dom
拆分的dom1
拆分的dom2
拆分的dom3
const start = async() => {// 拆分domconst domArr = this.splitChatDom()// 生成图片到imageListdomArr.forEach((domList,index) => {const dom = this.mergeChat(domList)document.body.appendChild(dom)this.createImage(dom,index)})await this.sleep(5000);// 合并图片this.mergeImage()await this.sleep(5000);// 下载this.download(this.canvas.toDataURL('image/png'),this.getFilename())
}
start()
把需要截图的子元素取出来,放到数组中
// 拆分chat子元素
splitChatDom() {let chat = document.querySelector("#chat")let chat_inner = chat.getElementsByClassName("chat-inner")[0]const dom_length = chat_inner.children.lengthlet childs = chat_inner.childrenlet domArr = []let i = 0;// 拆分个数const num = 20while (i < dom_length) {let arr = []for (let j=0; j< num && i+j<dom_length; j++) {const element = childs[i+j];arr.push(element)}domArr.push(arr)i+=num}return domArr
},
还原dom的父节点
mergeChat(domList) {let chat = document.createElement("div")chat.id = "chat"let chat_inner = document.createElement("div")chat_inner.className = "chat-inner"chat.appendChild(chat_inner)// console.log(domList);domList.forEach((dom) => {chat_inner.appendChild(dom)})return chat
},
分别截图
// 根据dom创建图片
createImage(dom,index) {domtoimage.toPng(dom, { quality: 1 }).then((dataUrl) => {this.imageList[index] = dataUrlthis.heightList[index] = dom.offsetHeight})
},
合并截图
// 合并图片
mergeImage() {this.canvas = nulllet canvas = document.createElement("canvas")let context = canvas.getContext("2d")context.scale(0.8,0.8)const scale = 0.8;const width = 1000 * scale; // 确保canvas的尺寸和图片一样const canvas_height = this.heightList.reduce((a,b)=>a+b-170) * scale;canvas.width = widthcanvas.height = canvas_heightlet sumHeight = 0for (let i = 0; i < this.imageList.length; i++) {const dataUrl = this.imageList[i];const height = this.heightList[i]let img = new Image()img.src = dataUrlimg.width = widthimg.height = heightimg.onload = () => {context.drawImage(img,0,sumHeight,width,height * scale)sumHeight += (height - 170) * scalethis.mergeFlag[i] = true}}this.canvas = canvas
},
暂停方法,需要在异步方法中调用
sleep(time){return new Promise((resolve)=>{setTimeout(()=>{resolve();}, time)})
},
方法二:效率低
def save_screenshot(url, fp_pic):chrome_options = webdriver.ChromeOptions(); chrome_options.add_experimental_option("excludeSwitches", ['enable-automation']);driver = webdriver.Chrome(options=chrome_options);driver.get(url)time.sleep(5)# 获取要截图的dom的高度chat = driver.find_element_by_id("chat")dom_height = chat.get_attribute("offsetHeight")offset_top = chat.get_attribute('offsetTop')page_height = 500driver.set_window_size(1080, page_height)# 滚动到要截图的位置#driver.execute_script("arguments[0].scrollIntoView();", chat)driver.execute_script('window.scrollBy(0,{});'.format(int(offset_top)))driver.save_screenshot('temp.png')n = int(dom_height) // (page_height-85) # 需要滚动的次数base_mat = np.atleast_2d(Image.open('temp.png')) # 打开截图并转为二维矩阵for i in range(n):print(i,page_height*(i+1))driver.execute_script('window.scrollBy(0,{});'.format(page_height-85)#'window.scrollTo(0,{});'.format(page_height*(i+1)+int(offset_top)))driver.save_screenshot(f'temp_{i}.png') # 保存截图mat = np.atleast_2d(Image.open(f'temp_{i}.png')) # 打开截图并转为二维矩阵base_mat = np.append(base_mat, mat, axis=0) # 拼接图片的二维矩阵Image.fromarray(base_mat).save(fp_pic, format='PNG')os.remove(f'temp_{i}.png')os.remove('temp.png')driver.quit()if __name__ == "__main__":url = ''save_screenshot(url,'aaa.png')# 缩放图片img = cv2.imread('aaa.png')img = img[:,:1250]img = cv2.resize(img,None,fx=0.64, fy=0.64, interpolation = cv2.INTER_CUBIC)cv2.imwrite('aaa.png',img)
dom截图——探究长截图的极限相关推荐
- 如何翻滚截屏_电脑端文档如何滚动截图(长截图)?
我们都知道,在手机端某些安卓的手机支持长截图,或叫做滚动截图.那么你知道在电脑端如何对excel或者word进行滚动截图吗? 不知道不要紧,看完这篇文章你就知道啦,并且以后可以完美应用到学习.工作当中 ...
- 使用selenium将网页保存网页截图,长截图,html文件,mhtml文件
最近在做网页分析需要爬取很多的网页,然后就使用selenium进行了一系列的操作,最后可以保存网页的首页截图,整体截图(包含所有滚动区域),HTML源文件和MHTML源文件,整理后的代码如下: 邮箱, ...
- 浏览器截图方法(长截图、node截图、指定区域截图)
1.打开需要截屏的页面,按键盘上的F2(或者Ctrl+Shift+I)打开浏览器控制台 2.Ctrl+shift+P进入搜索框,输入"screen": 这里有四种截图模式,点击需要 ...
- iShot 1.7.8 中文版 (支持长截图的截图工具)
iShot 是一款适用于Mac优秀的截图工具.功能全面,支持:区域截图.窗口截图.长截图.延时截图.屏幕录制以及截图标注.这里要特别表扬一下iShot的延时全屏截图以及快速标注工具.对于小编这种重度依 ...
- 必备!iShot 1.7.6 中文版 (支持长截图的截图工具)
iShot 是一款适用于Mac优秀的截图工具.功能全面,支持:区域截图.窗口截图.长截图.延时截图.屏幕录制以及截图标注.这里要特别表扬一下iShot的延时全屏截图以及快速标注工具.对于小编这种重度依 ...
- 安卓上的微软 Edge 浏览器新增支持长截图
据 MSPoweruser 报道,安卓上的微软 Edge 浏览器正在获得一项新功能,允许用户进行长截图,类似于安卓版 Chrome 浏览器的做法.目前,Edge Canary 频道提供了长截图的功能, ...
- 实用!你不知道的小技巧,电脑快速实现屏幕长截图
在日常工作中,我们经常需要用到屏幕长截图这个功能,而要实现这个功能往往需要下载好几个软件,而且经常截图的效果并不如意. 其实国民软件QQ目前已经有了长截图功能. 首先下载QQ最新版,然后在需要截图的页 ...
- 手机屏大字滚动_在iPhone手机中,实现长截图的几种方法
如何在iPhone手机中,实现长截图功能,是小伙伴们一直以来讨论的问题.其实在自带的Safari浏览器中,是支持长截图功能.但如若是需要截取其他软件或者系统界面,可能就只能依赖于第三方App了接下来就 ...
- 如何优雅的完成长截图?
安利一个截长图的工具ScreenShotTools. ScreenShotTools ScreenShotTools是一个Android长截图工具.目的是轻松搞定常见的View截图功能. 目前功能有: ...
最新文章
- wangEditor编辑器中解析html图文信息问题(三)
- OTA整包的制作流程(未完)
- STC89C52RC内部EEPROM编程
- java开发爱恩斯坦棋,爱恩斯坦棋计算机博弈关键技术研究
- Python分析《我们与恶的距离》豆瓣剧评
- java基础 ArrayList集合基本方法演示
- linux usermod修改用户所在组方法
- elk 概念整理 集群状态 - yellow
- 空间三维技术重现“山水林田湖草”管理沙盘
- tplink无线网卡的linux,Linux系统下怎么用TP-Link的无线网卡?
- HTML常用的元素介绍
- ajax网页没有办法采集,Ajax网页采集方法(最新) - 八爪鱼采集器
- 阿西莫夫定律:自动驾驶汽车算不算机器人?该不该伤人?
- 情感日记:2009年12月24日平安夜—“马头琴”
- 360浏览器中页面打开如何默认极速模式
- 【电路】电容(二)——滤波电容
- vue打印问题(分页打印、批量打印条形码)
- 从与迪思杰签约 看浪潮主机生态如何布局?
- 港科夜闻|香港科技大学(广州)与广东联通签署多方位战略合作协议
- python连接hive步骤(不出错版)