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를 사용해야 합니다.
매개변수
| 매개변수 | 설명 | 기본값 |
|---|---|---|
output |
출력 PNG 파일 경로 | /tmp/screenshot.png |
--width |
CSS 픽셀 단위의 뷰포트 너비 (기사: 1200, 대시보드: 1440-1920) | 1200 |
--dpr |
디바이스 픽셀 비율 (2 = 레티나, 단 파일 크기는 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(...)]포함)을 제거합니다.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는 데이터를 가져오고 렌더링하는 데 시간이 필요하므로 10,000~15,000을 사용하십시오 |
--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
복사





집
