全页截图
全页截图 (Full Page Screenshot)
通过 Chrome DevTools Protocol 对任何网页进行全页截图。生成一张包含所有内容的单张 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 并启用 "Allow remote debugging for this browser instance"。
工作流
方案 A:对已打开的标签页截图(推荐用于需要登录的页面)
1. 列出可用标签页:
node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" --list2. 通过标题/URL 确定目标 ID,然后执行捕获:
node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" <targetId> /tmp/screenshot.png --width 1200 --dpr 1方案 B:对指定 URL 截图(打开后台标签页 $\rightarrow$ 捕获 $\rightarrow$ 关闭)
node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" --url "https://example.com" /tmp/screenshot.png --width 1200 --dpr 1 --wait 15000> 注意: --url 模式会创建后台标签页。对于需要身份验证的页面(如 SSO、登录墙),请使用方案 A。
参数说明
| 参数 | 描述 | 默认值 |
|-----------|-------------|---------|
| output | 输出 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核心能力
1. SPA 滚动容器扩展 — 检测 overflow-y: auto/scroll 容器,通过滚动触发懒加载,随后移除溢出限制(包括 Tailwind 的 h-[calc(...)]),确保所有内容在单次渲染中完整呈现。
2. DOM 稳定性检测 — 在 readyState=complete 之后,持续监测 DOM 元素数量直到稳定。这确保了 SPA 框架已完成动态内容的渲染。
3. 触发懒加载 — 逐步滚动视口以触发 IntersectionObserver 回调,并等待所有 <img> 元素加载完成。
4. 超长页面分块捕获 — 超过 16,000px 的页面将以 8,000px 为块进行捕获,并使用 Python PIL 自动拼接。若未安装 PIL,则分别保存分块图片。
5. Chrome 自动发现 — 读取 DevToolsActivePort 文件以查找调试端口。若失败,则尝试探测 9222, 9229, 9333 端口。
6. CDP 代理回退 — 当 CDP 代理持有浏览器 WebSocket 时,脚本将回退到使用代理 API 端点 (/eval, /screenshot, /scroll) 进行捕获。
工作原理
1. 发现 Chrome 调试端口
2. 通过 WebSocket (CDP) 连接
3. 附加到目标页 / 创建后台标签页反面模式 (Anti-Patterns)
| 不要这样做 | 建议这样做 |
|--------|-----------|
| 对高度超过 10,000px 的页面使用 --dpr 2 | 使用 --dpr 1 以避免 Chrome 内存问题 |
| 对需要认证/SSO 的页面使用 --url | 在用户已登录的标签页上使用 --list + targetId |
| 为 SPA 设置低于 5000 的 --wait | SPA 需要时间获取数据并渲染;建议使用 10000-15000 |
| 在未先执行 --check 的情况下直接截屏 | 始终验证 Chrome 调试功能是否可用 |
| 为所有页面硬编码统一的视口宽度 | 文章类使用 1200,仪表盘/表格类使用 1440+ |
| 跳过输出验证 | 截屏后始终使用 sips 或 file 命令进行验证 |
故障排除
| 现象 | 原因 | 解决方法 |
|---------|-------|-----|
| "Cannot find Chrome debugging port" | 未启用远程调试 | 打开 chrome://inspect/#remote-debugging 并启用 |
| "WebSocket connection timeout" | CDP 代理占用连接 | 脚本会自动回退到代理 API |
| 截屏为空白/白色 | 页面尚未加载完成 | 增加 --wait 的值 |
| 底部被截断 | 滚动容器未展开 | 脚本会自动处理;如果问题持续请提交 Issue |
| 内存溢出 (Out of memory) | 页面极高 + 高 DPR | 将 --dpr 降低至 1 和/或减小 --width |
| "PIL not available for stitching" | 未安装 Python Pillow | 使用 pip3 install Pillow 安装,或接受独立的分块文件 |
交叉引用
engineering/browser-automation— 基于 CDP/Playwright 的通用浏览器自动化模式
engineering/performance-profiler— 可与视觉截屏互补的性能分析方法