ディレクトリ構造を保ったままWebページをダウンロードする
指定したWebページが読み込むファイルを、ディレクトリ構造を保ったままダウンロードするスクリプト(slimebundle)を書きました。
git clone https://github.com/takenspc/slimebundle.git cd slimebundle slimerjs slimebundle.js -u http://example1.com/foo/bar/
このスクリプトは指定したURLを、SlimerJSで開き、読み込まれた画像やCSS、JavaScriptなどをまとめてローカルに保存します。ただし、Origin(スキームとホストとポートの組み合わせ)が同じファイルのみ保存します。
例えば、http://example1.com/foo/bar/ が次のファイルを読み込んでいたとしましょう。
- http://example1.com/css/foo.css
- http://example1.com/js/foo.js
- http://images.example1.com/other.jpg
- http://example2.com/js/other.js
この場合、このスクリプトを実行したディレクトリにexample1.comというディレクトリができ、必要に応じてサブディレクトリが作られます。最終的にダウンロードされるファイルの構成は次のようになります。
このスクリプトはURLが「/」で終わっていると勝手にindex.htmlを追加します。また、Originの異なるother.jpgやother.jsは保存されません。通常のファイル以外にも、XMLHttpRequestなどでやりとりしているデータも保存します。
ローカルに保存する際のファイル名は、クエリー(?foo=bar)やフラグメント(#foo)を除いたものになります。foo.html?foo=bar#fooはfoo.htmlとして保存されます。クエリーやフラグメントを除いたことなどにより、保存ファイル名が同じものになる場合があります。この場合、先にダウンロードした内容は後でダウンロードした内容で上書きされます。例えば、あるページでfoo.html?foo=1の次にfoo.html?foo=2が読み込まれていた場合、このスクリプトで保存されるfoo.htmlはfoo.html?bar=2の内容になります。
また、このスクリプトにはファイルのダウンロード以外にもページのスクリーンショットを撮る機能とエラーが発生したリソースをコンソールに出力する機能があります。スクリーンショットはページのURLがfoo/bar/の場合、foo/bar/index.html.pngとして保存されます。
オプション
画面幅の指定
ページの画面幅は--widthや--heightオプションで指定できます。
slimerjs slimebundle.js -u http://example1.com/foo/bar/ --width 1024 --height 768 slimerjs slimebundle.js -u http://example1.com/foo/bar/ -i 1024 -e 768
保存するコンテンツの種類
このスクリプトは、ページが読み込んでいるファイルが動画のような大きなファイルであってもダウンロードしようとします。また、ファイルに書き出すために、読み込んだデータをメモリーに保存しています。このため、巨大なファイルではそれだけメモリーも消費します。必要なコンテンツの種類が分かっている場合には-cオプションで保存するファイルの種類を指定できます。ファイルの種類はMIMEタイプをあらわす正規表現をカンマ区切りで指定します。ただし、-uオプションで指定したページは-cオプションに関わらず保存されます。
例えば、PNG画像(image/png)を選んでダウンロードするには次のように指定します。
slimerjs slimebundle.js -u http://example1.com/foo/bar/ -c image/png
PNG画像(image/png)とテキストファイル系(text/htmlやtext/cssなど)を選んでダウンロードするには次のように指定します。
slimerjs slimebundle.js -u http://example1.com/foo/bar/ -c image/png,text/.+
なお、-cオプションにカンマが含まれている正規表現を指定しても正しく解釈されません。
ファイルの上書き
このスクリプトを同じディレクトリで続けて実行すると、1回目でダウンロードしたファイルも、2回目以降にダウンロードされれば上書きされます。-sオプションを指定すると、ローカルに既にファイルがあったら、上書きしないようにすることができます。
slimerjs slimebundle.js -u http://example1.com/ -s slimerjs slimebundle.js -u http://example1.com/foo/bar/ -s
特定機能のスキップ
ファイルの保存機能、エラーが発生したリソースの情報を出力機能、スクリーンショットの取得機能はそれぞれスキップすることができます。
slimerjs slimebundle.js -u http://example1.com/foo/bar/ --skip-saving --skip-error-resources --skip-screenshot
- --skip-saving
- ファイルの保存をスキップ
- --skip-error-resources
- エラーが発生したリソースをコンソールに出力する機能をスキップ
- --skip-screenshot
- スクリーンショットの取得をスキップ
作ってみて
PhantomJS 2.0ではグローバルスコープにURLオブジェクトが見えますが、
new URL("https://example.org/")
しても空のオブジェクト{}
が返ってくるので全く使えません。var input = "https://example.org/"; var url = new URL(input); url.origin // => undefined
PhantomJSでBasic認証の情報を設定すると、どのホストに対しても同じユーザー名とパスワードを送信するので実用的ではありませんが、SlimerJSにはもう少しまともな認証情報設定APIがあるようです。
- phantomjsifyを使うと、PhantomJS/SlimerJS用スクリプトでcommanderが使えるようになりました。しかし、--helpや-hなどはPhantomJS/SlimerJSで処理されるようで、commanderからは見えないようです。
PhantomJSは1.7からCommonJSをサポートしているそうなのですが、ドキュメントに見当たらず、PhantomJS 1.7のリリースノートを見るまで知りませんでした。