MHTML(*.mhtファイル)をLinuxで使う方法

こんなものはいかがか?

WindowsのIEではMHTMLという形式で、Webページ全体を保存することができる。MHTMLはメールの添付ファイルの形式をアーカイブ形式として使っている。なぜこのような形式を採用したのか理解しようとする必要はない(たぶんContent-Locationヘッダを使いたかっただけ でしょうけど)。

普通にIEで保存するとヘッダを書き換えられたりタグの大文字小文字をいじられたり空白が削られたり勝手にインデントがつけられたりする(f*ck!)が、まあHTMLの意味は変わらないので、表示だけなら再現できるようになっている。

そこで、mht.pyなんていうものを作ってみた。tarに似せたインタフェースでWebページを保存したり展開したりできる。Linux上のPython 2.2.3とかである程度は動作確認している。mozilla等のブラウザはmhtファイルに対応していないが、mht.pyを使えばmhtファイルをLinuxに持ってきて展開して読むことが可能になる。いずれはCGIとかのインタフェースをつけて、Webだけで完結させようかな。

イメージとしては、こんな感じ。

Usage: mht.py (tar like)
  ex. mht.py -cvf output.mht http://some.site/url/ ...
      mht.py -xvf input.mht -C outdir/
      mht.py -tvf input.mht

ところでIEからmhtに保存するとHTMLはquoted-printableでエンコードされ、画像その他はbase64でエンコードされることが多い(必ずしもそうではない)。しかしWindowsのquoted-printableのデコードが不完全なようで、PythonのEncoders.encode_quopriで変換すると元に戻してくれず、大化けする。改行のデコードとかが死んでるみたいだ。しょうがないので全部base64にしてあげた(笑)。これなら再現してくれるが、中身を人間が読めなくなる。しかもサイズが増える。そのかわりgzipで圧縮できるようにしてあげたので許してもらえるのではないかと思う。…許せないか。

問題も残っている。例えばasahi.comをmht.pyで保存してIEで再現させると、一部の画像が消えてしまっている。これはまだ原因がわからない。アーカイブ中には該当するファイルがあるのだが…。

それとこれは致命的な問題かもしれないが、現在、リンクのたどり方が少々(というかかなり)不完全である。指定したURLから1つ先までしか保存しない。AとAREAのリンクは除外。つまりフレームの大本を保存しても、フレームの中にある画像が保存されないことになる。このへんは修正が必要だ。ソースを見ればそのいいかげんさがわかるだろう(笑)。

(追記) 2004-09-13 22:35

FirefoxでもMAF(mozdev.org)を使えば*.mhtを見れますね。ただローカルファイルしか見れない。mafは、独自のmafファイル(実はZIPファイルにRDFがついたやつ)とかZIPにしたりとかできるみたいだ。ローカルのテンポラリディレクトリの下に展開して、file://…で見ている。

(追記) 2004-09-14 09:30

なんで画像が見えないのか、わかった。IEはimg src=””とかのリンクを変更して保存しているからだった(mht.pyはオリジナルのファイルのまま保存、展開時にリンクを書き換える)。でもそこは変更したくないし、どうしようかな…

コメント

  1. mhtを展開するためのpythonサンプルコードを探していてここに辿りつきました。
    大変勉強になりました。ありがとうございます。

    1点だけうまくいかず、ハマったポイントがありましたので共有させていただきます。
    mhtファイル展開時にバイナリファイルが正常にデコードされない現象が見えておりました

    def output(self, outdir, fname_base=””, replace=True, msg=None):

    内の

    if ctype==”text/html”:

    の else 節で、ofile が “w” でopenされておりますため、decode されたバイナリが正常にファイルライトされないものと思われます。
    バイナリファイルを書き込む際は ofile を “wb” とすることで解決いたしました。
    浅学ゆえ、無用な指摘をしてしまった様でしたらご勘弁いただきたいです。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です