full-page-screenshot
alirezarezvani/claude-skills
使用 Chrome DevTools 协议捕获任何网页的全屏截图,支持单页应用(SPA)、延迟加载的图片以及超长页面,且完全无需外部依赖。
...展开全部全页截图
通过 Chrome DevTools 协议捕获任意网页的全页截图。生成一张包含所有内容的 PNG 图片——即使是需要滚动才能查看的部分也不例外。除 Node.js 22 及以上版本和已启用远程调试功能的 Chrome 浏览器外,无需任何外部依赖。
先决条件
- Node.js 22+(使用内置
WebSocket) - 已启用远程调试功能的Chrome/Chromium
检查环境是否就绪:
node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" --check
如果 Chrome 检查失败,请指导用户打开chrome://inspect/#remote-debugging并启用“允许对此浏览器实例进行远程调试”。
工作流
方案 A:对已打开的标签页进行截图(推荐用于已认证的页面)
- 列出可用标签页:
node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" --list
- 通过标题/URL 识别目标,然后进行截图:
node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" /tmp/screenshot.png --width 1200 --dpr 1
方案 B:对 URL 进行截图(在后台打开标签页、截图、关闭)
node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" --url "https://example.com" /tmp/screenshot.png --width 1200 --dpr 1 --wait 15000
注意:
--url模式会创建一个后台标签页。需要身份验证的页面(如 SSO、登录墙)应改用方案 A。
参数
| 参数 | 描述 | 默认值 |
|---|---|---|
输出 |
输出 PNG 文件路径 | /tmp/screenshot.png |
--width |
视口宽度(以 CSS 像素为单位)(文章:1200,仪表盘:1440-1920) | 1200 |
--dpr |
设备像素比(2 表示 Retina 模式,但文件大小为 4 倍) | 1 |
--wait |
页面加载超时(单位:毫秒)(仅限--url模式) |
15000 |
--css |
在捕获前注入的自定义 CSS(例如,隐藏元素) | — |
验证输出
# macOS
sips -g pixelWidth -g pixelHeight /tmp/screenshot.png
# Linux
file /tmp/screenshot.png
核心功能
SPA 滚动容器扩展— 检测
overflow-y: auto/scroll容器,滚动浏览以触发延迟加载,随后移除溢出约束(包括 Tailwind 的h-[calc(...)]),确保所有内容在单次渲染中完成。DOM 稳定性检测— 在
readyState=complete之后,持续监测 DOM 元素数量直至其趋于稳定。这可确保 SPA 框架完成动态内容的渲染。延迟加载触发— 逐步滚动视口以触发
IntersectionObserver回调,随后等待所有元素完成加载。针对超长页面的分块捕获— 超过 16,000px 的页面将按 8,000px 进行分块捕获,并使用 Python PIL 自动拼接。若 PIL 不可用,则回退为单独保存各分块。
Chrome 的自动发现— 读取
DevToolsActivePort文件以查找调试端口。若无法读取,则回退到探测端口 9222、9229、9333。CDP 代理回退机制— 当 CDP 代理持有浏览器的 WebSocket 连接时,脚本将回退至代理 API 端点(
/eval、/screenshot、/scroll)进行截图。
工作原理
1. 发现 Chrome 调试端口
2. 通过 WebSocket(CDP)连接
3. 附加到目标浏览器 / 创建后台标签页
4. 通过模拟域设置视口宽度
5. 等待:readyState + DOM 稳定性
6. 检测并展开滚动容器
7. 滚动页面(触发延迟加载)
8. 等待图片加载完成
9. 测量最终内容高度
10. Page.captureScreenshot(或分块捕获)
11. 如有需要,拼接分块(PIL)
12. 恢复视口、断开连接、清理
反模式
| 切勿 | 应采用 |
|---|---|
在高度超过 10,000px 的页面上使用--dpr 2 |
使用--dpr 1以避免 Chrome 内存问题 |
对需要身份验证/单点登录(SSO)的页面,请使用--url |
在用户已登录的标签页中使用--list+ targetId |
对于单页应用(SPA),将--wait设置为小于 5000 |
单页应用(SPA)需要时间来获取数据并渲染;建议设置为 10000-15000 |
捕获时无需先执行--check检查 |
始终确认 Chrome 调试功能可用 |
| 为所有页面硬编码视口宽度 | 文章页面使用 1200,仪表盘/表格页面使用 1440 以上 |
| 跳过输出验证 | 捕获后务必使用sips或file命令进行验证 |
故障排除
| 症状 | 原因 | 解决方法 |
|---|---|---|
| “找不到 Chrome 调试端口” | 未启用远程调试 | 打开chrome://inspect/#remote-debugging,启用该功能 |
| “WebSocket 连接超时” | CDP代理正在保持连接 | 脚本自动回退到代理 API |
| 空白/纯白截图 | 页面尚未加载 | 增加--wait参数的值 |
| 底部内容被截断 | 滚动容器未展开 | 脚本会自动处理此情况;若问题仍存在,请提交问题报告 |
| 内存不足 | 页面高度过高 + DPR 值过高 | 将--dpr降至 1 并/或缩小--width |
| “PIL 无法用于拼接” | 未安装 Python Pillow | 请使用pip3 install Pillow安装,或接受单独的切片文件 |
相关参考
engineering/browser-automation— 通过 CDP/Playwright 实现的通用浏览器自动化模式engineering/performance-profiler— 可与视觉捕获相辅相成的性能分析
---
name: full-page-screenshot
description: Capture full-page screenshots of any web page using Chrome DevTools Protocol, handling SPAs, lazy-loaded images, and very tall pages with zero external dependencies.
---
# Full 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.
## 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" --check
```
If Chrome check fails, instruct user to open `chrome://inspect/#remote-debugging` and enable **"Allow remote debugging for this browser instance"**.
## Workflow
### Option A: Screenshot an already-open tab (recommended for authenticated pages)
1. List available tabs:
```bash
node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" --list
```
2. 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
```
### Option B: Screenshot a URL (opens a background tab, captures, closes)
```bash
node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" --url "https://example.com" /tmp/screenshot.png --width 1200 --dpr 1 --wait 15000
```
> **Note:** `--url` mode creates a background tab. Pages requiring authentication (SSO, login walls) should use Option A instead.
### Parameters
| Parameter | Description | Default |
|-----------|-------------|---------|
| `output` | Output PNG file path | `/tmp/screenshot.png` |
| `--width` | Viewport width in CSS pixels (articles: 1200, dashboards: 1440-1920) | 1200 |
| `--dpr` | Device pixel ratio (2 = Retina, but 4x file size) | 1 |
| `--wait` | Page load timeout in ms (`--url` mode only) | 15000 |
| `--css` | Custom CSS to inject before capture (e.g., hide elements) | — |
### Verify Output
```bash
# macOS
sips -g pixelWidth -g pixelHeight /tmp/screenshot.png
# Linux
file /tmp/screenshot.png
```
## Core Capabilities
1. **SPA scroll container expansion** — Detects `overflow-y: auto/scroll` containers, scrolls through them to trigger lazy-loading, then removes overflow constraints (including Tailwind `h-[calc(...)]`) so all content renders in a single pass.
2. **DOM stability detection** — After `readyState=complete`, monitors DOM element count until it stabilizes. This ensures SPA frameworks finish rendering dynamic content.
3. **Lazy-load triggering** — Scrolls the viewport incrementally to fire `IntersectionObserver` callbacks, then waits for all `<img>` elements to complete loading.
4. **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.
5. **Auto-discovery of Chrome** — Reads `DevToolsActivePort` file to find the debugging port. Falls back to probing ports 9222, 9229, 9333.
6. **CDP Proxy fallback** — When a CDP proxy holds the browser WebSocket, the script falls back to proxy API endpoints (`/eval`, `/screenshot`, `/scroll`) for capture.
## 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 up
```
## Anti-Patterns
| Do NOT | Do instead |
|--------|-----------|
| Use `--dpr 2` on pages > 10,000px tall | Use `--dpr 1` to avoid Chrome memory issues |
| Use `--url` for authenticated/SSO pages | Use `--list` + targetId on a tab where user is logged in |
| Set `--wait` below 5000 for SPAs | SPAs need time to fetch data and render; use 10000-15000 |
| Capture without checking `--check` first | 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 `sips` or `file` command after capture |
## Troubleshooting
| Symptom | Cause | Fix |
|---------|-------|-----|
| "Cannot find Chrome debugging port" | Remote debugging not enabled | Open `chrome://inspect/#remote-debugging`, enable it |
| "WebSocket connection timeout" | CDP proxy holding the connection | Script auto-falls back to proxy API |
| Blank/white screenshot | Page not loaded yet | Increase `--wait` value |
| 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 `--dpr` to 1 and/or reduce `--width` |
| "PIL not available for stitching" | Python Pillow not installed | Install with `pip3 install Pillow` or accept separate tile files |
## Cross-References
- [`engineering/browser-automation`](../browser-automation/SKILL.md) — General browser automation patterns via CDP/Playwright
- [`engineering/performance-profiler`](../performance-profiler/SKILL.md) — Performance analysis that may complement visual captures





首页
