Chrome으로 렌더링해 모든 자바스크립트를 제거한 오프라인 웹 미러
kage는 실제 Chrome 렌더링으로 페이지의 최종 DOM을 캡처하고 자바스크립트를 제거해 네트워크 호출 없는 정적 미러와 ZIM 또는 자체 실행형 바이너리를 생성하는 도구다.
TL;DR
웹 페이지를 단순히 파일로 저장하면 자바스크립트 의존성으로 인해 콘텐츠가 사라지거나 외부 호출이 남는 문제가 발생했으며 kage는 이를 해결하기 위해 실제 Chrome으로 각 페이지를 렌더링하고 사람이 본 최종 DOM을 스냅샷한 뒤 모든 자바스크립트를 제거하고 CSS·이미지·폰트를 로컬화해 디스크에 정적 미러를 생성한다. 생성된 미러는 결정적 URL-경로 매핑으로 중복을 방지하고 ZIM 아카이브나 자체 실행형 바이너리, 네이티브 WebView 앱으로 패킹할 수 있어 배포와 보존이 용이하다. 단, ZIM 출력은 전체 텍스트 검색 인덱스를 생성하지 않으므로 검색 기능이 필요한 경우 별도 처리가 필요하며, WebView 기반 네이티브 빌드는 cgo와 플랫폼별 라이브러리 종속성을 요구한다. 결과적으로 kage는 동적 사이트의 정확한 오프라인 보존과 의존성 없는 배포를 동시에 충족시키는 실무적인 도구다.
주요 기능
- 렌더링한다. kage는 실제 헤드리스 Chrome 탭 풀을 구동해 페이지가 안정화될 때까지 기다린 다음 사람이 본 최종 DOM을 캡처한다. 이 방식은 클라이언트 사이드 렌더링 이후 생성된 콘텐츠와 lazy-loaded 자원을 포함해 정확한 정적 스냅샷을 얻는 데 유리하다.
- 스크립트를 제거한다. 캡처한 HTML에서 모든 <script>와 인라인 핸들러, javascript: URL을 제거해 디스크에서 열었을 때 어떠한 코드도 실행되지 않도록 만든다. 이 과정은 트래킹과 외부 네트워크 호출을 차단해 보존용 미러의 신뢰성을 보장한다.
- 자산을 로컬화한다. CSS의 url()과 이미지·폰트 참조를 재작성해 모든 자산을 로컬 경로로 내려받고 링크를 수정한다. 이렇게 하면 미러 폴더 또는 ZIM 내부에서 클릭 시 원래 사이트와 동일한 경로 해상도로 자원이 제공된다.
- 패킹과 배포를 지원한다. 만든 미러를 ZIM 아카이브로 압축하거나 미러를 포함한 자체 실행형 바이너리 또는 운영체제별 더블클릭 앱으로 포장할 수 있다. 이 옵션은 네트워크와 의존성이 없는 단일 전달물로 오프라인 배포를 단순화한다.
어떻게 동작하는가
kage는 시드 URL을 받아 headless Chrome 탭 풀로 페이지를 렌더링하고 렌더된 최종 DOM을 스냅샷한 뒤 모든 자바스크립트를 제거하고 CSS·이미지·폰트를 로컬 경로로 재작성해 디스크에 저장한다. 렌더링과 자산 다운로드를 분리된 작업 풀로 병렬 처리하며 URL-경로 매핑을 결정적으로 계산해 링크 재작성과 재시작 시 중복 다운로드를 방지한다. pack 단계는 이미 재작성된 미러 상대 경로를 그대로 ZIM 또는 실행파일 내부 항목으로 매핑해 추가 변환 없이 아카이브를 구성한다.
해결 문제
웹 페이지를 단순히 저장하면 자바스크립트에 의존하던 동적 콘텐츠가 사라지거나 외부 네트워크 호출로 빈 화면이 나타나는 문제가 발생했다. kage는 실제 브라우저 렌더링 후의 완성된 DOM을 캡처하고 스크립트를 제거하면서 자산을 로컬로 내려받아 네트워크 비의존적인 정적 미러를 만든다. 이로 인해 장기 보존, 오프라인 사용, 안전한 공유용 단일 파일 배포가 가능해졌다.
지금 주목받는 이유
오프라인 접근성과 보존성에 대한 실용적 수요, ZIM과의 상호운용성, Docker 이미지와 플랫폼별 패키지를 통한 손쉬운 배포 경로가 결합되어 실사용자에게 즉시 유용한 도구로 주목받고 있다. 또한 실제 브라우저 렌더링을 통해 동적 사이트의 정확한 스냅샷을 얻는 접근법이 신뢰성을 제공해 많은 스타를 얻었다. 다양한 배포 형식과 네이티브 창 옵션이 프로젝트의 채택을 촉진하고 있다.
차별점
- 실제 브라우저 렌더링을 사용한다. kage는 헤드리스 Chrome으로 페이지를 완전히 렌더링한 뒤 최종 DOM을 캡처하므로 클라이언트 사이드 렌더링 결과와 lazy-loaded 자원을 정확히 포함한다. 이 점은 단순한 HTML 스냅샷터나 HTTP 기반 크롤러와 구별되는 핵심 차별화 요소이다.
- 결정적 URL-경로 매핑을 적용한다. 각 URL이 일관된 로컬 파일 경로로 매핑되어 http/https와 슬래시 변형에도 중복 파일이 생성되지 않으며 재시작 시 이전 상태를 재사용할 수 있다. 이 매핑은 pack 단계에서 아카이브 내 항목 일대일 대응을 보장한다.
- ZIM과 자체 실행형 바이너리 등 배포 형식을 다양하게 지원한다. kage는 ZIM 표준 파일을 생성해 Kiwix 생태계와 상호운용 가능하며, 실행파일에 아카이브를 덧붙여 의존성 없는 뷰어로 배포할 수 있다. 이로 인해 수신자가 별도 소프트웨어 없이 콘텐츠를 열람할 수 있다.
- 네이티브 WebView로의 패킹을 선택적으로 지원한다. build-webview 태그를 사용하면 플랫폼 WebView를 링크해 팩된 뷰어가 브라우저 탭이 아니라 독립된 네이티브 창으로 열리며 사용자 경험이 더 앱에 가깝게 유지된다. 이 빌드는 cgo와 네이티브 라이브러리 의존성을 요구해 선택적으로 사용된다.
사용 사례
- 항공기나 원격지 같은 네트워크가 없거나 불안정한 환경에서 긴 형식의 웹 문서를 온전하게 읽기 위해 미러를 생성하고 단일 파일로 배포하는 용도로 적합하다. ZIM 또는 자체 실행형 바이너리를 이용하면 수신자가 별도 환경설정 없이 콘텐츠를 열람할 수 있다. 교육 자료, 아카이브, 조사 보고서 보관에 활용될 수 있다.
- 웹사이트 디자인 변경이나 서비스 종료로 인해 콘텐츠 접근성이 사라질 위험이 있는 사이트를 보존하는 아카이빙 워크플로의 일부로 사용된다. 결정적 매핑과 재시작 가능한 크롤링은 정기적인 스냅샷과 증분 갱신을 가능하게 한다. 저장된 미러는 원본 사이트의 의존성을 제거하고 장기 보존을 지원한다.
- 보안·프라이버시 요구가 높은 경우 네트워크 호출을 차단한 상태에서 원본과 동일한 보기 경험을 제공하려는 내부 배포 시 유용하다. 스크립트가 모두 제거되므로 트래킹과 외부 전화(home) 호출이 발생하지 않는다. 내부 문서화 및 규정 준수 목적의 자료 전달에 적합하다.
시작하기
가장 빠른 시작은 Go가 설치된 환경에서 go install github.com/tamnd/kage/cmd/kage@latest를 실행해 kage 바이너리를 설치한 뒤 kage clone <host>와 kage serve <mirror-dir>로 미러 생성과 로컬 서빙을 순차적으로 수행하는 것이다. Chrome/Chromium이 시스템에 있어야 하며, Docker 이미지를 이용하면 Chromium을 번들한 컨테이너로 동일한 작업을 실행할 수 있다. 미러를 단일 파일로 만들고 싶다면 kage pack <mirror>로 ZIM이나 실행형 바이너리로 패키징하면 된다.
요구사항
- Chrome 또는 Chromium이 호스트에 설치되어 있어야 하며 kage는 이를 자동으로 탐지하거나 --chrome 옵션으로 경로를 지정할 수 있다. 컨테이너 이미지를 사용할 경우에는 호스트에 브라우저가 없어도 Chromium이 포함된 이미지를 실행하면 된다. WebView 기반 네이티브 빌드를 생성하려면 cgo와 플랫폼별 WebView 라이브러리(WKWebView, WebView2, WebKitGTK)가 필요하다.
- Go 개발 환경이 필요하며 소스에서 빌드할 경우 make 기반 빌드 스크립트를 사용한다. 표준 빌드는 CGO_ENABLED=0로 크로스컴파일이 쉬우나 webview 태그로 빌드하면 cgo가 활성화되어 네이티브 종속성이 추가된다. 테스트 스위트는 Chrome 기반의 E2E 테스트를 포함하므로 로컬 환경 구성에 따라 추가 리소스가 요구될 수 있다.
- 디스크 용량은 미러링 대상 사이트의 규모에 따라 크게 달라지며 ZIM으로 패킹하면 압축 저장이 가능하다. 실행형 바이너리에 아카이브를 덧붙이면 바이너리 크기는 기본 실행파일 크기(약 13 MiB)와 미러 크기의 합이 된다. 많은 페이지와 대용량 미디어를 다룰 때는 출력 디렉터리와 I/O 성능을 고려해야 한다.
이미지 분석


3k
Stars
111
Forks
+212
Trending
0
조회수
관련 토론
아직 관련 토론이 없습니다.
댓글
댓글을 작성하려면 로그인이 필요합니다.