2P by GN⁺ | ★ favorite | 댓글 1개
  • 헤드리스 크롬으로 페이지를 렌더링해 사람이 봤을 최종 DOM을 스냅샷한 뒤, 모든 JavaScript를 삭제하고 CSS·이미지·폰트를 로컬 경로로 내려받아 코드 없이 동작하는 정적 사본 생성
  • "Save As"로 저장한 페이지가 시간이 지나면 빈 화면·멈춘 스피너·사라진 analytics 서버 접속 시도로 망가지는 문제 해결
    • 추적·네트워크 호출·예기치 못한 동작 없이 디스크에서 바로 열리는 .html 파일 제공
  • breadth-first 크롤링으로 robots.txt를 읽고 sitemap.xml에서 시작점을 잡으며 seed 호스트에 머무름
    • idempotent 특성으로 http·https나 trailing slash 유무와 무관하게 동일 페이지를 한 번만 가져옴
    • Ctrl-C 시 위치를 저장하고 재실행 시 이어가며, --refresh로 재렌더링, --force로 새로 시작
  • --max-pages, --max-depth, --scope-prefix, --subdomains, --scroll, --workers크롤 범위·동작 제어 flag 제공
  • kage pack으로 사본을 단일 파일로 압축, ZIM 아카이브 또는 사이트 자체로 동작하는 단독 실행 파일 중 선택
    • ZIM은 Kiwix 생태계와 호환되어 kiwix-serve나 Kiwix 데스크톱·모바일 앱에서도 열람 가능
    • 단독 바이너리는 받는 사람이 아무것도 설치할 필요 없으며, --base로 다른 OS용 viewer 생성 가능 (약 13 MiB + 사이트 용량)
  • 결정론적 패킹으로 같은 사본은 항상 byte-identical 파일 생성, archive UUID가 콘텐츠에서 도출되어 checksum·cache에 안전
  • webview 태그로 빌드 시 OS WebView(WKWebView·WebView2·WebKitGTK)를 사용해 브라우저 탭이 아닌 자체 창에서 열림
  • 처리 파이프라인: seed URL → headless Chrome 렌더링 → final DOM 스냅샷 → strip JS → 자산 로컬화 → 디스크 저장
  • MIT 라이선스

댓글과 토론

Hacker News 의견들
  • README의 데모 GIF가 어떻게 생성됐는지 흥미로워서 봤음: https://github.com/tamnd/kage/blob/01e75b87ecc893bbba7943c63...
    알고 보니 같은 작성자의 다른 프로젝트인 https://github.com/tamnd/ascii-gif를 사용함
    데모에 쓰인 스크립트는 https://github.com/tamnd/kage/blob/01e75b87ecc893bbba7943c63...에 있고, 실행 방법도 주석으로 들어 있음: ascii-gif render docs/demo/kage.tape -o docs/static/demo.gif
    https://github.com/charmbracelet/vhs 를 취향 강하게 감싼 래퍼처럼 보임

    • 터미널 구원자 asciinema의 복음을 들어보셨나요: https://asciinema.org/
    • $HOME/bin/에도 이런 식의 개인용 바이너리가 꽤 있음. delete-all-npm, clean-rust-cache, download-youtube-playlist, get-markdown 같은 것들인데, 명령을 외울 필요가 없어서 좋음
      가끔은 코딩 에이전트가 이런 도구들을 어떻게 호출해야 하는지도 알아서 찾아냄
    • GIF 대신 애니메이션 SVG로도 만들 수 있고, 텍스트 키프레임일 뿐이라 GIF보다 훨씬 작음: https://github.com/vytskalt/pseudoc/blob/main/assets/factori...
    • 참고로 다른 플랫폼인 Windows/macOS에서는 LiceCAP이 화면을 작은 GIF로 녹화하기에 훌륭한 도구임. Winamp와 Reaper DAW 작성자가 만든 것임: https://www.cockos.com/licecap/
    • VHS는 명령줄 영상 생성을 스크립트로 만들 때 훌륭함
  • 회사 위키를 오프라인에서도 쉽게 접근하게 해주고 싶을 때 이걸 쓸 수 있겠음. 예를 들면 휴대폰 신호가 안 잡히는 현장에서 유용한 문서가 위키에 있을 수 있음
    사이트 전체를 단일 바이너리로 묶을 수 있다는 점은 멋지지만, 별도의 서빙 프로세스가 필요 없는 버전이면 특히 좋겠음
    사이트 콘텐츠 아카이브를, 가능하면 내장된 형태로, 찾아볼 수 있는 약간의 JavaScript가 들어간 단일 HTML 진입점 shim 같은 방식도 가능해 보임

    • Hacker News에 올린 게 딱 맞는 자리였네요. 아이디어를 구현할지 고려해보겠음
      머릿속에는 이미 HTML을 Markdown으로 변환하는 스크립트/프로그램이 있어서, 실제로는 모든 것을 디스크에 Markdown 파일 폴더로 저장한 뒤 Git 저장소에 커밋할 수도 있음
  • 이거 훌륭함. Lovable 같은 데서 만든 누군가의 프로토타입을 오프라인 사본으로 받아서, 더 쉬운 형식으로 버전 관리와 공유를 하고 싶었음
    우리가 접근한 방식은 여기에 적어뒀음: https://productnow.ai/blogs/extracting-html-from-ai-prototyp...
    이제 이걸 살펴보고 일부를 바꿀 수 있는지 보겠음. 오프라인 미러라는 아이디어가 마음에 들고, 협업 관련 사용 사례가 훨씬 단순해짐

  • kage serve $HOME/data/kage/paulgraham.com이라고 되어 있는데, 결과물이 정적이라면 왜 서버가 필요한지 모르겠음. 브라우저에서 그냥 열 수 있게 만들 수는 없나?
    예를 들면 $ firefox $HOME/data/kage/paulgraham.com처럼 가능하면, kage가 설치되지 않은 기계에서도 결과물을 사용할 수 있음

    • 대신 python -m http.server를 쓸 수 있을 것 같음. 아직 시도해보진 않았지만 동작할 듯함
      실제로 Kage는 두 부분으로 되어 있음. 하나는 Chrome/Chromium 렌더링 이후 DOM을 캡처해서 페이지를 크롤링하고 깨끗한 HTML로 바꾸는 크롤러이고, 다른 하나는 결과를 Kiwix용 ZIM 파일이나 실행 파일로 패키징하는 pack/serve 구성요소임
    • 보통 그런 식으로 페이지를 로드하면 JavaScript가 차단
    • 그렇게 하면 아마 CORS 문제를 엄청 많이 만날 가능성이 큼
  • SingleFile [0]이 이보다 훨씬 견고한 버전이라고 봄
    JavaScript도 모두 제거하지만, 전송하기 쉬운 단일 HTML 파일로 전부 묶어줌. 웹 폰트나 이미지 같은 바이너리 자산은 base64 문자열로 들어감
    Puppeteer 기반 CLI도 제공함 [1]
    [0]: https://github.com/gildas-lormeau/singlefile
    [1]: https://github.com/gildas-lormeau/single-file-cli

    • 이 저장소는 웹페이지 하나만 저장하는 것처럼 보임
      여기서 구현 중인 건 하위 페이지까지 포함한 전체 웹사이트 미러링이라서, 오프라인에서도 전부 탐색할 수 있음. 예를 들면 paulgraham.com의 모든 에세이 같은 것임
    • SingleFile 정말 좋아함. Firefox 확장은 깔끔하게 저장하는 데 꽤 잘 동작함
      다만 Kage가 SingleFile 수준의 재현 품질과 HTTPTrack식 스파이더링 접근을 결합할 수 있다면 유망해 보임. 단일 페이지 앱은 아카이빙이 좀 까다로운데 Kage가 얼마나 잘 처리할지 궁금함
    • 링크 고마움. 이 단일 HTML 기능을 구현해보겠음. 있으면 좋아 보임
    • 컴퓨터의 아무 웹브라우저에서 File -> Save as 하는 것과 뭐가 다른가?
    • 나도 처음에 이걸 떠올렸고, 매우 우아한 해결책이라고 봄. 불필요하게 복잡하지도 않음
  • HTTP, 즉 HTTPS가 아닌 사이트를 복제해보려 했는데 navigation failed: net::ERR_NAME_NOT_RESOLVED가 나옴. http://로 프로토콜을 명시해도 마찬가지였음

  • 비행기에서 읽으려고 위키를 내려받을 때 httrack(https://www.httrack.com)을 써왔음. 완벽하진 않지만 이전에 찾은 것들보다는 나았음
    이것도 시도해보겠고, 결과가 좋으면 정말 기쁠 듯함

    • 추억 돋음. 20년쯤 전에는 인터넷이 여전히 비싼 전화 접속이라, PC방에 가서 HTTrack으로 웹사이트와 만화를 내려받고, 그때는 아주 크게 느껴졌던 128MB USB 메모리에 전부 복사한 다음 집에 가져와 오프라인으로 읽곤 했음
    • 위키만 놓고 보면 Kiwix를 쓰지 않을 이유가 있나? “공식” 릴리스가 아닌 경우에는 더 복잡하지만, ZIM 파일을 생성해주는 서비스들이 있음. 데스크톱 리더 앱은 내 경험상 꽤 좋았음
      https://wiki.openzim.org/wiki/Build_your_ZIM_file
      EDIT: https://get.kiwix.org/en/solutions/applications/kiwix-reader...
    • https://github.com/archiveteam/grab-site나 browsertrix가 어떤 사람들에게는 더 쓰기 쉬울 수 있음. data.gov 자료가 내려가기 전에 많이 저장할 때 쓰였던 도구임
  • 수년간 오래된 웹사이트 아카이브를 꽤 모았음. 재미있는 건 못생긴 HTML 덤프가 “완벽한” 아카이브보다 더 유용했다는 점임
    시간이 갈수록 RSS를 더 좋아하게 된 이유 중 하나도 그거임. 10년쯤 된 피드는 정성껏 보존된 애플리케이션형 웹사이트보다 오늘날 더 사용하기 쉬운 경우가 많음

    • RSS 피드를 생성하고 아카이빙하는 프로젝트를 하고 있음. 크롤러가 시작된 시점부터 전체 이력을 보존함
      조금 정리한 뒤 곧 오픈소스로 공개할 예정임
  • 이건 사이트에 꽤 큰 부하를 만들 가능성이 있어 보임. 복제 속도를 조절하거나 이미지/비디오를 피하는 설정이 있나?
    웹사이트의 일부만 가져오는 방법도 있는지 궁금함

    • 이걸 새 이슈로 만들어줄 수 있나? 나중에 처리하겠음. 지금 내 시간으로 새벽 1시지만, 누군가 관심을 가져줘서 기쁨
    • 그냥 AI 크롤러인 척하면 문제 해결됨
  • 깔끔한 프로젝트고 아이디어가 마음에 듦
    빠르게 읽어보니 Chrome을 --no-sandbox로 실행하던데, 그럴 만한 이유가 있나? 보안 측면에서는 좋은 생각이 아닐 가능성이 큼. 이유가 없다면 샌드박스를 켜두는 걸 권함
    어쨌든 멋진 작업임

    • --no-sandbox는 Docker에서 필요함. 아마 대부분 Docker에서 실행될 거라고 가정한 것 아닐까?