読者です 読者をやめる 読者になる 読者になる

C++ ときどき ごはん、わりとてぃーぶれいく☆

Wonder Rabbit Projectのなかのひとのブログ。主にC++。

動的ウェブサイトを静的ウェブサイトへ変換する方法

ASP.NETなどのいわゆる一般に言うCMSなど動的なフレームワークを用いるなどしているウェブサイトを何らかの理由(もう更新しない、閲覧用のスナップショットにしたい、など)で静的ウェブサイトへ変換したいニーズは普通にあるかと思います。

更新停止するサイトそのものは遺しておきたいけれど、動的ウェブフレームワークで稼働させる必要が無い場合、静的コンテンツ群、つまるところHTMLや画像などにしてしまえば、エンドユーザーの閲覧の快適さも良くなりますし、サーバー負荷も減ります。流行りのエコでございます。

以下、今の私ならこうするよっていう手順を紹介します。

0. 準備

  • 最近のLinuxを適当に使える状態にします。(wgetmsrp が必要になります。)
    • MacOSXの事はよくわかりませんが、UNIX系なら紹介する手順はどうにかなるでしょう。
    • Windowsの人は捨てましょう余程低スペックなPCでなければ仮想マシンにArch Linuxなど入れると良いでしょう。
      • mingwCygwinでも構いませんが、Windows故に何かあっても知りません。

1. wget でとりあえず取得

wgetします。オプション -m は丸ごとミラーの意味、 --restrict-file-names=nocontrol を付けるとダウンロードしたファイルがURLエンコードされなくなります。URLエンコードはブラウザーとサーバーの間のHTTP通信に必要なのであって、サーバーがローカルファイルを取得する際にまでURLエンコードされている必要はありませんので。

 wget -m --restrict-file-names=nocontrol http://www.example.com/

※↑追記2も見てね!

2. msrp でアレコレ修正

例えば、ASP.NETのBlogEngine.NETのウェブサイトを静化する為にwgetしてあるとしましょう。すると、URLのファイル名部分が hogehoge.aspx?fuga=gagaga みたいなものが大量にあると思います。ここで ? はURLにおいてそれ以前をファイル名、それ以降をクエリとしてウェブサーバーは普通処理しますから、ファイル名そのものに ? が付いているとエンドユーザーはHTTP経由でアクセスできません。さらに、Windowsユーザーは例えmingwCygwinやSUAを使ったところで、所詮はファイルシステムに ? を持ったファイル名を扱わせる事まではできませんし、いずれにしてもファイル名に ? があるのは面倒です。

そこで、 msrp というツールで置換します。玄人はここで find と xargs と sed で十分だと言うかもしれませんが、不十分です。 msrp は「検索対象のディレクトリに含まれる全てのファイルとディレクトリの名前とファイルの中身を正規表現で置換」する事に特化したツールです。
(※いやいや sed に加えて mv もすればいいだけじゃない、そう言う玄人はどうそどうぞご自由に…。)

msrp でごりごりと作業しちゃう前にバックアップを取っておくと良いでしょう。

 cp -r www.example.com www.example.com.backup

msrp しましょう。

 msrp '\.aspx\?' '.aspx-' www.example.com

これで、例えば www.example.com/hogehoge.aspx?fuga=gagaga という名前だったファイルや拾ってきたファイル郡に含まれるリンク(wgetが拾ったファイルが有るという事はどこかでそのファイルを参照している)のhrefなどが www.example.com/hogehoge.aspx-fuga=gagaga に変わります。

また、ファイル名で ? を含む物を全て - に置き換えてしまうというだけなら、

 msrp '\?' '-' -c -d www.example.com

とかやっても良いです。 -c でファイルの中身は触れない(コンテンツ無視)、 -d でディレクトリ名には触れない、となります。ちなみに -f とするとファイル名には触れない、 -i を付けると大文字小文字を無視してマッチ(いぐのーらけーす)という動作にも対応できます。

他にも修正が必要なパターンが動的サイトの仕組み次第でアレコレあると思いますが、ひとまず nginx や lighttpd などの適当なウェブサーバーで回収した www.example.com をホストして Firefox や Chromium で表示を確認してみましょう。
(※この時、サーバーが返すレスポンスヘッダーに含まれる Content-type がデフォルトで text/html になるようにしておくと、拡張子が .aspx でも .html 同様に処理される様になります。)

3. ブラウザで確認しながら msrp

Firefoxなら firebug 、または Chromium などではデフォルトでF12的なウェブ制作者向けのツールを使えます。そこで、ネットワークのスタティクスなどを見ると、どのURLへのアクセス要求が静化したページに埋め込まれており、どの要求がエラーになっているかが一目瞭然です。

あとはそれを見ながら msrp で静化したサイトに含まれるURL文字列をファイル名やディレクトリ名ごと、がっさごっそとregexでreplaceしてあげるだけです。コツと動的ウェブサイトの仕掛けの癖がつかめれば単純なregexによるreplace作業を数回行う程度で終わります。数年間動かしていたブログだとかを静化する場合、ファイル数が多いのでちょっとだけ処理時間は必要かも知れませんけどね。


※「ブラウザで確認しながら」は表示を目で確認するんじゃありませんよ・w・; firebug とか F12 で動くソレとかでネットワークのリクエスト、レスポンスの状態を見るんですよ・w・;

※最後の状態の動的ウェブサイトの構成データ群はアーカイブしてバックアップしておいた方が良いでしょう。もしかしたら、将来また必要になるデータや、あるいはシステムの再稼働なんて事もあるかもしれませんしね。

※ msrp とか使わなくてもそれも Vim で出来るよ!とか kdevelop のプラグインでできるよ!とか Visual Studio …とか、ええ、ええ、いいですよお好きなものを使って下さいw ただまあ、今回はこの msrp っていうのがCUIでさくっと使えてとても快適だなー・・・でもあんまり知られてないツールなんじゃないかなーと思ったので紹介したかったんです!


<追記1>

便利なツールなので、はてなキーワードにも msrp を登録しました。

<追記2>

まるごとwgetする時に、 -m --restrict-file-names=nocontrol オプションでは回収が無限に終わらない可能性もあります。そんな時は、 -m オプションを展開して -l オプションを具体的に指定するか、省略してデフォルトの5になるようにすると良いです。これは、 -m オプション = -r -N -l inf -nr オプション群、なのですが、 -l が再帰的に取得する階層を意味し、デフォルトは5、-mの時はinf(無制限)となる為です。なお、 -r は再帰取得、 -N は上書き保存、-nrはFTPから取得する際のリスト情報保持を指示するオプションです。

また、 -m --restrict-file-names=nocontrol の代わりに、 -r -N -k --restrict-file-names=windows を指示すると、もしかしたらその後の msrp での作業量が大幅に減らせるかもしれません。

どういう事かと言うと、 --restrict-file-names=windows を指示する事で、URLに含まれる ? や / は @ や %2F に変換され、 -k によりそれらURLとファイル名の再マッピング処理が自動的に行われる為です。この方法が上手くできた場合に残る作業は、CSSからのデータ取得関連(CSSファイルからの相対パス画像)や、コンテンツが静化された事や移転先を知らせるメッセージの挿入などで済む可能性が高いです。