我们正在使用Puppeteer来截取包含Canvas的页面,并且Canvas的高度可能超过一屏(即需要滚动才能看到全部内容)。由于Puppeteer的截图功能默认只能截取当前视口(viewport)内的内容,因此对于超过一屏的内容,我们需要采取一些策略来获取完整截图。
可能的解决方案:
由于问题中提到Canvas可能高于一屏,而且我们不知道具体高度,所以第一种方法可能不总是可行(尤其是在极端高度的情况下)。因此,我们通常采用第二种方法。
步骤:
a. 设置视口大小,比如宽度为页面宽度,高度为一屏的高度(例如1000像素)。
b. 获取整个Canvas元素的高度(通过page.evaluate)。
c. 根据视口高度和Canvas高度,计算需要滚动截图的次数。
d. 循环滚动页面,每次滚动后截取当前视口,并保存截图。
e. 使用图像处理库(如jimp或pngjs)将这些截图拼接成一张完整的长图。
但是,Puppeteer本身也提供了对全页面截图的支持(通过设置fullPage: true
),但是全页面截图对于某些使用Canvas的页面可能无法正确捕获,因为全页面截图是基于页面布局的,而Canvas是动态绘制的。特别是,如果Canvas的内容是通过WebGL动态渲染的,那么全页面截图可能无法捕获到Canvas的全部内容。因此,我们需要手动滚动并截图。
因此,我们选择手动滚动截图并拼接的方式。
注意:在滚动和截图之间,我们需要等待一小段时间以确保Canvas绘制完成(尤其是如果Canvas内容在滚动时动态加载)。
示例代码:
const numScreenshots = Math.ceil(totalHeight / viewportHeight);
但是,如果Canvas的内容在滚动时不会动态加载(即整个Canvas已经在内存中),那么我们可以尝试另一种方法:调整视口高度为整个Canvas的高度,然后截图整个视口。这种方法简单,但可能因为视口过大而失败。
因此,我们优先采用滚动截图的方式。
下面是代码示例(使用puppeteer和jimp进行拼接):
当使用 Puppeteer 截取超过一屏高度的 Canvas 图片时,需要特殊处理滚动和渲染问题。以下是完整解决方案:
动态高度检测
scrollHeight
获取完整内容高度强制重绘技巧
Puppeteer 高级参数
fullPage: true
:截取完整页面captureBeyondViewport: true
:捕获视口外内容deviceScaleFactor: 2
:生成高清截图滚动渲染处理
networkidle2
等待网络请求如果遇到空白区域:
WebGL Canvas 额外处理:
如果上述方法失效,可尝试:
注意:某些Canvas可能有内容保护机制(如游戏),此时需要联系网站所有者获取截图权限。