Kage: Shadow Websites into Script-Free Offline Binaries

Kageは、ウェブサイトをスクリプトなしの閲覧可能なミラーとしてクローンすることで、「壊れた」オフライン保存の問題を解決するために設計されたツールです。外部JavaScriptへの依存やリンク切れが頻繁に発生する従来の「名前を付けて保存」機能とは異なり、Kageは実際のブラウザでページをレンダリングし、最終的なDOMのスナップショットを取得し、すべてのJavaScriptを削除することで、コンテンツがオフラインでも機能し、プライバシーが保たれることを保証します。

Core Functionality: Rendering and Sanitization

Kageは、ヘッドレスChromeインスタンスを駆動して、人間が目にするのと全く同じようにページをキャプチャすることで、ウェブサイトの永続的なオフライン版を作成します。プロセスは特定のパイプラインに従います: Seed URL $\rightarrow$ Headless Chrome (Render) $\rightarrow$ Final DOM (Snapshot) $\rightarrow$ Strip JS (Sanitize) $\rightarrow$ Localize Assets (Rewrite Links) $\rightarrow$ Disk.

すべてのスクリプトを削除することで、Kageはトラッキング、ネットワークコール、および現代的なシングルページアプリケーションに共通する「スピナー」効果を排除します。出力結果は、.htmlファイルと、ローカライズされたCSS、画像、フォントを含む予約された_kageディレクトリで構成されます。

Deployment and Usage Options

Kageは、さまざまな環境のニーズに合わせて、ツールをインストールして実行するための複数の方法を提供します:

  • Go Installation: go install github.com/tamnd/kage/cmd/kage@latest
  • Prebuilt Binaries: .deb, .rpm, .apkパッケージとして利用可能。
  • Docker: Chromiumを同梱したコンテナイメージ(ghcr.io/tamnd/kage)により、ローカルのChromeインストールが不要になります。

Cloning and Mirroring

kage cloneコマンドは、礼儀正しい幅優先探索(breadth-first crawl)を実行します。robots.txtを尊重し、sitemap.xmlをシードとして使用します。主な機能は以下の通りです:

  • Scope Control: --scope-prefixを使用して、サイトの特定のセクションにクロールを制限できます。
  • Depth and Page Limits: --max-pagesおよび--max-depthを使用して、データの量を制御できます。
  • Lazy Loading Support: --scrollフラグは、スクロール時にのみロードされる画像をキャプチャするために自動スクロールをトリガーします。
  • Idempotency: Kageはページを書き込むファイルによってキーを管理するため、プロトコル(HTTP vs HTTPS)に関係なく、同じページが複数回取得されるのを防ぎます。

Serving Offline Content

現代のブラウザはセキュリティ上の理由から、file://プロトコルを介したローカルファイルの読み込みを制限することが多いため、kage serveはリンクやアセットが正しく解決されるようにローカルHTTPサーバーを実行します。

Packing Mirrors into Portable Artifacts

Kageは、ユーザーがディレクトリベースのミラーを単一のファイルに圧縮して、共有や長期保存を容易にすることを可能にします。

ZIM Archives

Kageは、ミラーをZIMファイル形式にパックできます。これは、WikipediaやStack Overflowをオフラインで保存するためにKiwixなどのプロジェクトで使用されているオープン標準です。ZIMは文書化された標準であるため、Kageで作成されたファイルは、あらゆるZIMリーダー(Kiwixのデスクトップ、Android、またはiOSアプリなど)で開くことができ、ベンダーロックインを防ぐことができます。

Self-Contained Binaries

--format binaryフラグを使用すると、KageはウェブサイトアーカイブをKageの実行可能ファイル(executable)のコピーに結合します。これにより、実行時にサイトをオフラインで提供する単一のバイナリが作成されます。ターゲットマシンに外部の依存関係やZIMリーダーが必要になることはありません。

より統合された体験を求める場合は、webviewタグを使用してKageをビルドすることで、これらのバイナリがブラウザのタブではなく、ネイティブOSのウィンドウ(macOSではWKWebView、WindowsではWebView2、LinuxではWebKitGTKを使用)でサイトを開くことが可能です。

Technical Architecture

KageはGoで書かれており、いくつかの専門化されたパッケージに整理されています:

  • clone: クロールのフロンティア、レンダリングワーカー、および再開状態を管理します。
  • browser: ヘッドレスChromeの制御とDOMスナップショットの取得を扱います。
  • sanitize: スクリプト、イベントハンドラー、および URLを削除します。
  • asset: CSS、画像、およびフォントをダウンロードしてローカライズします。
  • zim: ZIMリーダーおよびライターの純粋なGo実装です。

Community Insights and Alternatives

Hacker Newsでのコミュニティの議論では、ウェブアーカイブのこの手法に対して、いくつかの代替案や検討事項がハイライトされています:

  • Alternative Tools: ユーザーは、アセットをbase64文字列として使用してすべてを単一のHTMLファイルにパックする堅牢な代替案としてSingleFile、および伝統的なWikiミラーリング用のHTTrackに言及しています。
  • Security Concerns: 一部のユーザーは、オンラインで共有されたバイナリを実行することはセキュリティリスクであると指摘し、あるユーザーはWindows Securityが生成されたバイナリを、潜在的に不要なソフトウェア(potentially unwanted software)としてフラグを立てる可能性があると指摘しました。
  • Comparison to wget: このツールは、本質的に、まずレンダリングを行ってJavaScript-heavyなページを扱えるようにした、より現代的なwget --mirrorのバージョンと言えます。

"The ugly HTML dumps have been more useful than the 'perfect' archive... A feed from 10-ish years ago is highly usable today than a carefully preserved (application) website."

この考え方は、複雑なアプリケーション状態の保存よりも、シンプルでスクリプトなしのHTMLを優先するというKageの哲学を哲学を強調しています。

Sources