full-page-screenshot
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseFull Page Screenshot
全屏页面截图
Capture a full-page screenshot of any web page via Chrome DevTools Protocol. Produces a single PNG that includes all content — even portions that require scrolling. Zero external dependencies beyond Node.js 22+ and Chrome with remote debugging enabled.
通过Chrome DevTools Protocol捕获任意网页的全屏截图。生成包含所有内容的单张PNG图片——即便是需要滚动才能查看的部分。除了Node.js 22+和开启远程调试的Chrome外,无需任何外部依赖。
Prerequisites
前置条件
- Node.js 22+ (uses built-in )
WebSocket - Chrome/Chromium with remote debugging enabled
Check environment readiness:
bash
node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" --checkIf Chrome check fails, instruct user to open and enable "Allow remote debugging for this browser instance".
chrome://inspect/#remote-debugging- Node.js 22+(使用内置)
WebSocket - Chrome/Chromium 已开启远程调试
检查环境就绪状态:
bash
node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" --check若Chrome检查失败,请告知用户打开并启用**"允许此浏览器实例进行远程调试"**。
chrome://inspect/#remote-debuggingWorkflow
工作流程
Option A: Screenshot an already-open tab (recommended for authenticated pages)
选项A:捕获已打开的标签页(推荐用于需认证的页面)
- List available tabs:
bash
node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" --list- Identify the target by title/URL, then capture:
bash
node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" <targetId> /tmp/screenshot.png --width 1200 --dpr 1- 列出可用标签页:
bash
node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" --list- 通过标题/URL确定目标,然后执行捕获:
bash
node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" <targetId> /tmp/screenshot.png --width 1200 --dpr 1Option B: Screenshot a URL (opens a background tab, captures, closes)
选项B:捕获指定URL的页面(在后台打开标签页、完成捕获后关闭)
bash
node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" --url "https://example.com" /tmp/screenshot.png --width 1200 --dpr 1 --wait 15000Note:mode creates a background tab. Pages requiring authentication (SSO, login walls) should use Option A instead.--url
bash
node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" --url "https://example.com" /tmp/screenshot.png --width 1200 --dpr 1 --wait 15000注意:模式会创建后台标签页。需要认证的页面(SSO、登录墙)应使用选项A。--url
Parameters
参数说明
| Parameter | Description | Default |
|---|---|---|
| Output PNG file path | |
| Viewport width in CSS pixels (articles: 1200, dashboards: 1440-1920) | 1200 |
| Device pixel ratio (2 = Retina, but 4x file size) | 1 |
| Page load timeout in ms ( | 15000 |
| Custom CSS to inject before capture (e.g., hide elements) | — |
| 参数 | 说明 | 默认值 |
|---|---|---|
| 输出PNG文件路径 | |
| 视口宽度(CSS像素,文章类页面建议1200,仪表盘类建议1440-1920) | 1200 |
| 设备像素比(2=视网膜屏,但文件大小会变为4倍) | 1 |
| 页面加载超时时间(仅 | 15000 |
| 捕获前注入的自定义CSS(例如隐藏元素) | — |
Verify Output
验证输出结果
bash
undefinedbash
undefinedmacOS
macOS
sips -g pixelWidth -g pixelHeight /tmp/screenshot.png
sips -g pixelWidth -g pixelHeight /tmp/screenshot.png
Linux
Linux
file /tmp/screenshot.png
undefinedfile /tmp/screenshot.png
undefinedCore Capabilities
核心功能
-
SPA scroll container expansion — Detectscontainers, scrolls through them to trigger lazy-loading, then removes overflow constraints (including Tailwind
overflow-y: auto/scroll) so all content renders in a single pass.h-[calc(...)] -
DOM stability detection — After, monitors DOM element count until it stabilizes. This ensures SPA frameworks finish rendering dynamic content.
readyState=complete -
Lazy-load triggering — Scrolls the viewport incrementally to firecallbacks, then waits for all
IntersectionObserverelements to complete loading.<img> -
Tiled capture for very tall pages — Pages exceeding 16,000px are captured in 8,000px tiles and automatically stitched using Python PIL. Falls back to saving tiles separately if PIL is unavailable.
-
Auto-discovery of Chrome — Readsfile to find the debugging port. Falls back to probing ports 9222, 9229, 9333.
DevToolsActivePort -
CDP Proxy fallback — When a CDP proxy holds the browser WebSocket, the script falls back to proxy API endpoints (,
/eval,/screenshot) for capture./scroll
-
SPA滚动容器扩展 — 检测容器,滚动触发懒加载,然后移除溢出限制(包括Tailwind的
overflow-y: auto/scroll),使所有内容一次性渲染。h-[calc(...)] -
DOM稳定性检测 — 在后,监控DOM元素数量直至稳定。确保SPA框架完成动态内容渲染。
readyState=complete -
触发懒加载 — 逐步滚动视口以触发回调,然后等待所有
IntersectionObserver元素加载完成。<img> -
超长页面分片捕获 — 高度超过16000px的页面会被分成8000px的分片捕获,并通过Python PIL自动拼接。若PIL不可用,则会单独保存分片文件。
-
Chrome自动发现 — 读取文件查找调试端口。若失败则尝试探测9222、9229、9333端口。
DevToolsActivePort -
CDP代理降级方案 — 当CDP代理持有浏览器WebSocket连接时,脚本会降级使用代理API端点(、
/eval、/screenshot)进行捕获。/scroll
How It Works
工作原理
1. Discover Chrome debugging port
2. Connect via WebSocket (CDP)
3. Attach to target / create background tab
4. Set viewport width via Emulation domain
5. Wait: readyState + DOM stability
6. Detect & expand scroll containers
7. Scroll through page (trigger lazy-load)
8. Wait for images to complete
9. Measure final content height
10. Page.captureScreenshot (or tiled capture)
11. Stitch tiles if needed (PIL)
12. Restore viewport, detach, clean up1. 发现Chrome调试端口
2. 通过WebSocket连接CDP
3. 附加到目标标签页/创建后台标签页
4. 通过Emulation域设置视口宽度
5. 等待:页面就绪 + DOM稳定
6. 检测并扩展滚动容器
7. 滚动页面(触发懒加载)
8. 等待图片加载完成
9. 测量最终内容高度
10. 执行Page.captureScreenshot(或分片捕获)
11. 若需要则拼接分片(使用PIL)
12. 恢复视口、断开连接、清理资源Anti-Patterns
反模式
| Do NOT | Do instead |
|---|---|
Use | Use |
Use | Use |
Set | SPAs need time to fetch data and render; use 10000-15000 |
Capture without checking | Always verify Chrome debugging is available |
| Hardcode viewport widths for all pages | Use 1200 for articles, 1440+ for dashboards/tables |
| Skip output verification | Always verify with |
| 请勿这样做 | 建议做法 |
|---|---|
对高度超过10000px的页面使用 | 使用 |
对需认证/SSO的页面使用 | 在用户已登录的标签页上使用 |
为SPA页面设置 | SPA需要时间获取数据并渲染,建议设置10000-15000毫秒 |
未先执行 | 始终先验证Chrome调试是否可用 |
| 为所有页面硬编码视口宽度 | 文章类页面用1200,仪表盘/表格类用1440+ |
| 跳过输出结果验证 | 捕获后务必用 |
Troubleshooting
故障排查
| Symptom | Cause | Fix |
|---|---|---|
| "Cannot find Chrome debugging port" | Remote debugging not enabled | Open |
| "WebSocket connection timeout" | CDP proxy holding the connection | Script auto-falls back to proxy API |
| Blank/white screenshot | Page not loaded yet | Increase |
| Truncated at bottom | Scroll container not expanded | Script handles this automatically; file an issue if it persists |
| Out of memory | Very tall page + high DPR | Reduce |
| "PIL not available for stitching" | Python Pillow not installed | Install with |
| 症状 | 原因 | 解决方法 |
|---|---|---|
| "无法找到Chrome调试端口" | 未开启远程调试 | 打开 |
| "WebSocket连接超时" | CDP代理持有连接 | 脚本会自动降级使用代理API |
| 截图空白/白屏 | 页面未加载完成 | 增大 |
| 截图底部被截断 | 滚动容器未扩展 | 脚本会自动处理此问题,若仍存在请提交issue |
| 内存不足 | 超长页面+高DPR | 将 |
| "PIL不可用于拼接分片" | 未安装Python Pillow | 执行 |
Cross-References
交叉参考
- — General browser automation patterns via CDP/Playwright
engineering/browser-automation - — Performance analysis that may complement visual captures
engineering/performance-profiler
- — 通过CDP/Playwright实现通用浏览器自动化的方案
engineering/browser-automation - — 可与视觉捕获互补的性能分析工具
engineering/performance-profiler