ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Puppeteer ScreenshotOptions 全面解析:用 Page.screenshot 精确控制截图输出

Puppeteer ScreenshotOptions 全面解析:用 Page.screenshot 精确控制截图输出 Puppeteer ScreenshotOptions 全面解析用 Page.screenshot 精确控制截图输出【免费下载链接】puppeteerJavaScript API for Chrome and Firefox项目地址: https://gitcode.com/GitHub_Trending/puppeteer1/puppeteer导读本文以 Puppeteer 官方 API 文档中的ScreenshotOptions接口见 puppeteer.screenshotoptions.md为核心系统讲解 Puppeteer 页面截图Page.screenshot的完整配置体系。ScreenshotOptions是所有截图操作的“总开关”它决定了截图的文件格式、编码方式、输出路径、截取范围全页还是局部区域以及透明背景等行为。读完本文你将能够熟练组合type、quality、fullPage、clip、captureBeyondViewport、omitBackground、encoding、path、fromSurface、optimizeForSpeed这十项参数写出精确、可控、可直接落地到自动化脚本中的截图代码。ScreenshotOptions 是什么一切截图能力的配置入口在 Puppeteer 中页面截图的主入口是Page.screenshot而ScreenshotOptions就是它的参数类型。从源码看该接口被定义在 packages/puppeteer-core/src/api/Page.ts是页面截图与元素截图共享的基座类型页面级截图page.screenshot(options?)元素级截图elementHandle.screenshot(options?)其专用参数类型ElementScreenshotOptions直接extends ScreenshotOptionsscreenshot()方法具有两个重载签名见 api/Page.tsasync screenshot( options: ReadonlyScreenshotOptions {encoding: base64}, ): Promisestring; async screenshot(options?: ReadonlyScreenshotOptions): PromiseUint8Array;这意味着当encoding指定为base64时返回的是stringBase64 编码的图像数据否则返回Uint8Array二进制图像数据。这一返回值约定是理解整个ScreenshotOptions的起点。属性总览与默认值ScreenshotOptions共包含 10 个可选属性官方文档以表格形式完整列出如下PropertyModifiersTypeDescriptionDefaultcaptureBeyondViewportoptionalbooleanCapture the screenshot beyond the viewport.falseif there is noclip.trueotherwise.clipoptional[ScreenshotClip](https://link.gitcode.com/i/57e608de9920f3a8fb06b078655de5eb)Specifies the region of the page/element to clip.—encodingoptionalbase64 \| binaryEncoding of the image.binaryfromSurfaceoptionalbooleanCapture the screenshot from the surface, rather than the view.truefullPageoptionalbooleanWhentrue, takes a screenshot of the full page.falseomitBackgroundoptionalbooleanHides default white background and allows capturing screenshots with transparency.falseoptimizeForSpeedoptionalboolean—falsepathoptionalstringThe file path to save the image to.—qualityoptionalnumberQuality of the image, between 0-100. Not applicable topngimages.—typeoptional[ImageFormat](https://link.gitcode.com/i/6f1970ea25bb3502241644f437c3fc5a)—png与接口定义同步的还有两个相关类型api/Page.tsScreenshotClip继承自BoundingBox即x、y、width、height并额外增加一个可选字段scale默认值1ImageFormat是一个字面量联合类型png | jpeg | webp。关键属性逐一深入解析下面按“截什么、存哪里、怎么存”的逻辑线逐项拆解各属性并结合仓库源码说明其内部影响。type 与 quality输出格式与压缩质量type决定图像格式可选png、jpeg、webp默认png。quality用于设置有损压缩质量取值范围0-100 闭区间且“不适用于png图像”。这两者之间存在严格的校验与联动体现在Page.screenshot的实现中if (options.quality ! undefined) { if (options.quality 0 || options.quality 100) { throw new Error( Expected quality (${options.quality}) to be between 0 and 100, inclusive., ); } if ( options.type undefined || ![jpeg, webp].includes(options.type) ) { throw new Error( ${options.type ?? png} screenshots do not support quality., ); } }也就是说越界会抛错对 png 传quality同样会抛错。在 CDP 底层实现packages/puppeteer-core/src/cdp/Page.ts中quality会先被Math.round()取整再传给协议const {data} await this.#primaryTargetClient.send( Page.captureScreenshot, { format: type, optimizeForSpeed, fromSurface, ...(quality ! undefined ? {quality: Math.round(quality)} : {}), ...(clip ? {clip: {...clip, scale: clip.scale ?? 1}} : {}), captureBeyondViewport, }, );可见type、quality、optimizeForSpeed、fromSurface、clip、captureBeyondViewport最终都会一一映射到 CDP 的Page.captureScreenshot协议参数上。path按文件扩展名自动推断格式path用于把截图直接保存到磁盘扩展名决定截图类型如果未显式传入type源码会解析path的后缀小写后匹配自动推断type——png→pngjpeg/jpg→jpegwebp→webp见 api/Page.ts相对路径基于当前工作目录解析不传path则不落盘图像数据仍会以Uint8Array形式返回除非encoding: base64。仓库自带的 examples/screenshot.js 与 examples/screenshot-fullpage.js 都是直接依托该机制的可运行示例前者演示基本截图、后者演示整页长图保存。encodingbinary 与 base64 两种交付形态encoding默认binary。两种取值的差异直接决定screenshot()返回类型与是否写盘api/Page.tsconst data await this._screenshot(options); if (options.encoding base64) { return data; } const typedArray stringToTypedArray(data, true); await this._maybeWriteTypedArrayToFile(options.path, typedArray); return typedArray;即base64返回字符串并跳过文件写入适合直接内嵌到 JSON、上报远端等场景binary返回Uint8Array并且只有当提供了path时才写盘。fullPage整页长图fullPage: true将捕获整页内容而非仅当前视口默认false。它的实现路径与captureBeyondViewport深度耦合具体逻辑见 api/Page.ts当fullPage与clip同时出现时直接抛出错误clip and fullPage are mutually exclusive二者互斥当fullPage: true且captureBeyondViewport: false时代码会先在隔离世界isolated realm中读取document.documentElement的scrollWidth/scrollHeight临时把 viewport 调整到整页尺寸截图完成后再通过stack.defer()恢复原 viewport。注释明确提醒这种方式可能受页面 CSS 与 JavaScript 影响反之fullPage: true且captureBeyondViewport未显式指定默认走“捕获超出视口内容”的协议路径即clip缺省时直接把整页交给浏览器协议捕获。注意fullPage还支持在defaultViewport为null的情况下工作——对应测试见 test/src/screenshot.test.ts 中的 “should take fullPage screenshots when defaultViewport is null”。clip 与 scale精确框选裁剪区域clip用于指定要捕获的页面/元素区域类型为ScreenshotClip。该类型除了继承BoundingBox的x、y、width、height外还支持一个scale缩放因子默认1用于在捕获时对裁剪区域进行缩放。Page.screenshot会对clip做三件事api/Page.ts浅拷贝避免外部修改影响捕获过程校验宽高必须为正数width/height小于等于 0 时抛错与fullPage互斥校验随后通过roundRectangle(normalizeRectangle(...))把小数坐标归一化、四舍五入为整数矩形。而在 CDP 实现中clip.scale未指定时会被补齐为1clip.scale ?? 1再发送给浏览器协议。clipscale的组合在测试套件中有专门覆盖例如 screenshot.test.ts 中的 “should use scale for clip”。captureBeyondViewport是否突破视口边界捕获captureBeyondViewport决定“是否捕获视口之外的区域”其默认值比较特殊——官方文档给出的默认是没有clip时为false否则为true。这个“条件默认”在源码中有明确落点缺省值填充函数setDefaultScreenshotOptions会把未显式设置的captureBeyondViewport置为true但当用户既没给clip也没给fullPage时screenshot() 主流程 会再把它强制改写为false——因为此时目标就是当前视口当给出clip却把captureBeyondViewport置为false时CDP 实现cdp/Page.ts会读取window.visualViewport的尺寸与滚动偏移用getIntersectionRect把裁剪框与视口求交集即只截取“落在视口内的那部分”该行为的边界情况有专门测试screenshot.test.ts“should get screenshot bigger than the viewport”和“should clip clip bigger than the viewport without captureBeyondViewport”。omitBackground透明背景截图omitBackground: true会隐藏默认白色背景从而得到带透明通道的图像默认false。注意该能力只对支持透明度的格式有意义。CDP 实现cdp/Page.ts仅在type为png或webp时才生效if (omitBackground (type png || type webp)) { await this.#emulationManager.setTransparentBackgroundColor(); stack.defer(async () { await this.#emulationManager.resetDefaultBackgroundColor().catch(error { this.logger?.(DEBUG_PREFIXES.error)?.(error); }); }); }其内部通过 emulation 机制先把默认背景色改为透明截图结束后再自动恢复默认背景色。若在WebDriver BiDi协议下设置omitBackground: true则会直接抛出UnsupportedOperation异常见下文 BiDi 差异小节。fromSurface 与 optimizeForSpeed两个底层调优开关fromSurface默认true文档描述为“从 surface 捕获而非从 view当前视图树捕获”。从 CDP 协议映射看它会被直接透传给Page.captureScreenshot。日常使用保持默认即可若手动改为falseCDP 将使用基于 view 的捕获路径。optimizeForSpeed默认false同样被直接透传给 CDP 协议。它属于底层性能优化提示在功能无额外描述的情况下建议仅在明确需要时开启。默认值集中在哪里setDefaultScreenshotOptions用户传入的所有缺省项最终统一由setDefaultScreenshotOptions补齐export function setDefaultScreenshotOptions(options: ScreenshotOptions): void { options.optimizeForSpeed ?? false; options.type ?? png; options.fromSurface ?? true; options.fullPage ?? false; options.omitBackground ?? false; options.encoding ?? binary; options.captureBeyondViewport ?? true; }这段代码即官方文档“Default”列的权威出处typepng、fromSurfacetrue、fullPagefalse、omitBackgroundfalse、encodingbinary、optimizeForSpeedfalse而captureBeyondViewport的“条件默认”则由主流程二次修正完成。底层协议差异CDP 与 WebDriver BiDi 的支持边界Puppeteer 同时支持 ChromeCDP与 Firefox/WebDriver BiDi 两条实现路径ScreenshotOptions并非在所有协议下都能完整生效。WebDriver BiDi 的实现packages/puppeteer-core/src/bidi/Page.ts会对以下取值显式抛出UnsupportedOperationomitBackground: true—— BiDi 不支持optimizeForSpeed: true—— BiDi 不支持fromSurface: false—— BiDi 不支持clip.scale存在且不等于1—— BiDi 不支持裁剪缩放。此外BiDi 下当captureBeyondViewport为false且给出了clip时由于 BiDi 的裁剪框始终基于文档坐标实现会在页面上下文中读取window.visualViewport.pageLeft/pageTop把裁剪框换算成视口坐标后再发送。也就是说跨浏览器Firefox WebDriver BiDi场景下尽量避开透明背景、速度优化与 clip 缩放否则会触发 UnsupportedOperation 异常这些高级能力目前是 Chrome CDP 专属。完整实战示例下面给出组合使用ScreenshotOptions的典型场景均基于import puppeteer from puppeteer;之后获得的browser、page对象。1. 最基础保存 PNG 到磁盘await page.goto(https://example.com); // 未传 type但 path 以 .png 结尾自动推断为 png await page.screenshot({path: screenshot.png}); // 等价于显式声明 await page.screenshot({type: png, path: screenshot.png});2. 整页长图await page.screenshot({fullPage: true, path: fullpage.png}); // 仓库内完整可运行示例见 examples/screenshot-fullpage.js3. 精确框选区域 2 倍缩放// 从页面左上角 (0,0) 开始截取 800x600 区域并按 2 倍缩放输出 await page.screenshot({ clip: {x: 0, y: 0, width: 800, height: 600, scale: 2}, path: region.png, }); // 注意fullPage 与 clip 互斥不能同时设置4. JPEG 质量 Base64 输出// quality 仅适用于 jpeg/webpjpeg 会得到一张不透明图片 const base64 await page.screenshot({ type: jpeg, quality: 80, encoding: base64, }); // base64: string可直接上传或内嵌5. 透明背景 PNG// 仅对 png/webp 生效配合 type 一起使用 await page.screenshot({ type: png, omitBackground: true, path: transparent.png, });6. 直接拿内存中的二进制数据const bytes: Uint8Array await page.screenshot(); // 默认 encodingbinary // 未传 path不会落盘由调用方自行处理 bytes相关类型与扩展ElementScreenshotOptionsElementScreenshotOptions在ScreenshotOptions之上只扩展了一个字段scrollIntoView默认true。它服务于ElementHandle.screenshot截图前先把目标元素滚动进视口。也就是说ScreenshotOptions中除fullPage之外的绝大多数语义clip变成“元素的包围盒”、omitBackground、type、quality等同样适用于元素截图这与仓库测试中 “should capture full element when larger than viewport”“should use element clip” 等用例screenshot.test.ts相互印证。小结ScreenshotOptions是 Puppeteer 截图能力的“控制面板”十条参数各自独立又彼此联动type/quality/encoding决定“生成什么”path决定“存到哪里”clip/fullPage/captureBeyondViewport决定“截多少”omitBackground/fromSurface/optimizeForSpeed决定“怎么截”。结合 setDefaultScreenshotOptions 的默认值逻辑、screenshot()主流程的校验顺序quality 越界、png 禁 quality、clip 与 fullPage 互斥以及 CDP / BiDi 两套协议实现的差异边界即可写出既符合规范又跨浏览器稳健的截图代码。需要进一步了解裁剪框与图像格式类型的定义可继续阅读 ScreenshotClip、BoundingBox 与 ImageFormat 三个接口文档。【免费下载链接】puppeteerJavaScript API for Chrome and Firefox项目地址: https://gitcode.com/GitHub_Trending/puppeteer1/puppeteer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表