full-page-screenshot
alirezarezvani/claude-skills
Chrome DevTools Protocol を使用して、外部依存関係を一切必要とせずに、SPA や遅延読み込みされる画像、非常に長いページにも対応しながら、あらゆるウェブページの全ページスクリーンショットをキャプチャできます。
...すべて拡張します全ページスクリーンショット
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を開き、「このブラウザインスタンスのリモートデバッグを許可する」を有効にするよう指示してください。
ワークフロー
オプション 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 を使用してください。
パラメータ
| パラメータ | 説明 | デフォルト |
|---|---|---|
output |
出力PNGファイルのパス | /tmp/screenshot.png |
--width |
ビューポートの幅(CSSピクセル単位)(記事:1200、ダッシュボード:1440~1920) | 1200 |
--dpr |
デバイスピクセル比(2 = Retina、ただしファイルサイズは4倍) | 1 |
--wait |
ページの読み込みタイムアウト(単位:ms)(--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(...)]`を含む)を解除し、すべてのコンテンツが1回のパスでレンダリングされるようにします。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を使用する |
Chromeのメモリ問題を回避するために--dpr 1を使用する |
認証済みページや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
full-page-screenshotをインストール
スキルファイルをダウンロードし、.claude/skills/ ディレクトリに解凍してください。
ZIPをダウンロードリポジトリをクローンし、スキルファイルをプロジェクトにコピーしてください。
git clone https://github.com/alirezarezvani/claude-skills/tree/main/engineering/skills/full-page-screenshot # Copy SKILL.md to your .claude/skills/ directory
コピー





家
