21
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

MHTMLを1ファイルのHTMLに変換する

Last updated at Posted at 2017-11-26

概要

HTMLを1ファイルに保存するのに便利だったのでMHTML形式を多用していたが、MHTML形式も終焉が近そうなので何とかしようというもの。

Microsoft EdgeではMHTMLファイルを開くことはできず、FirefoxもVer.56まではUnMHTというアドオンでMHTMLファイルの読み込み・保存ができたが、Firefox QuantumでWebExtensionsになってUnMHTが使えなくなってしまった。WebExtensionsでは独自スキーマを扱えないことから今後似たようなアドオンが出てくる望みも薄い。Google ChromeはMHTMLファイルを開くことはできるものの完全にはサポートしていないようで、IE11やUnMHTでは正しく表示できるファイルでもGoogle Chromeではスタイルが適用されなかったり画像が表示されないといった問題があった。現在MHTMLファイルを正しく表示できるのはIE11のみでIEも終焉が近い。

そんなわけで数百ファイルあるMHTMLファイルをできるだけ簡単に変換できるもので、かつ、表示内容もできるだけ元のままにできるものとして、インラインタイプのHTMLファイルを採用してみた。

MHTML形式

MHTML形式はMIMEのマルチパートを利用した形式で、HTML形式のメールとして多く利用されているがHTMLを1ファイルに保存する用途にも利用できる。
先頭にメールと同じヘッダ情報があり、外部参照のCSSやJavascript、画像はbase64エンコードされて同一ファイル内に書かれている。日本語をそのまま扱えないので、テキストエディタで開いて読むのは厳しい。

インラインタイプのHTMLファイル

正式には何というのか不明だが、外部参照のCSSはstyleタグ、Javascriptはscriptタグ内に全て内容が書かれていて、画像はimgタグのsrc属性にdata:image/<形式>;base64,<画像をbase64エンコードした文字列>と指定することで直接埋め込んだもの。画像の使い回しができないので同一画像を多用しているとファイルサイズが大きくなってしまうが、HTMLファイルなので大抵のブラウザで同じように表示できる。

形式変換

MHTML形式をインラインタイプのHTMLファイルに変換する方法について適当にGoogle検索すると、nodeのモジュールに色々ありそうだったので試してみた。

mhtml
https://www.npmjs.com/package/mhtml

html-inline
https://www.npmjs.com/package/html-inline

mhtmlはMHTMLファイルに埋め込まれたCSSやjavascript、画像をそれぞれのファイルとして保存し、普通のHTMLファイル+外部リソースという形式にしてくれるもの。

html-inlineは、HTMLから参照しているCSSやjavascript、画像をインラインタイプのHTMLファイルに変換してくれるもの。

ほかにも

mhtml2html
https://www.npmjs.com/package/mhtml2html

というのもあったが、UsageにChromeでしかテストしていないとあるように、IEやUnMHTで保存したMHTMLファイルはうまくパースできないようだった。

(2017/12/9追記)
html-inlineだとbackgroundで指定されている画像が無視されてしまっていたのでちょっと試してみたのが

inline-assets
https://www.npmjs.com/package/inline-assets

これだとbackground画像もうまく扱えるようだった。ただ、画像のBase64エンコードでutf8に変換してファイルを読み込んでいて、画像が壊れてしまっていたので修正してPRを出しておいた。
CSSなどで指定されているものの見つからない画像があるとエラーになってしまっていたので、そこは手を加えて無視するようにしてみた。

インストールと使用方法

各モジュールは

npm install -g mhtml
npm install -g html-inline

とグローバルモジュールとしてインストールしておく。
あとは、

mhtml foo.mht output
html-inline -i output/index.html --ignore-links -o foo.html
rm -rf output

とするとfoo.mhtというMHTMLファイルをインラインタイプのHTMLファイルに変換したものがfoo.htmlとして作成される。
--ignore-linksと指定したのは、linkタグで参照しているリンク先がないものがあり、変換でエラーが発生していたため。
ほかにもいくつかオプションがあるので各ドキュメントを参照するとよい。

補足

内容を確認しつつ1ファイルずつ変換してみたところ、iframeを使っていたりwikiなどを保存したMHTMLファイルだとうまくHTMLファイルに変換できないようで、そういった少し特殊なものは手作業で移行することになりそう。

21
17
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?