Edited at

あるページの画像をガッっと一気にダウンロードしようぜ!

あるWebページから画像をいっぺんにDLしたいときってあるよね!

いちいちマウスで右クリックして「名前をつけて画像を保存」をして、これを繰り返して、ってめんどくさいですよね。

ワンライナーで解決しましょう!


一括DLコマンド

curl -Ls $URL | xmllint --html --xpath '//img/@src' - | xargs -n 1 | cut -d= -f2 | sed 's/^\/\//https:\/\//' | xargs -n 1 curl -L#O

$URL がURL部分になりますので、目的のURLに置き換えましょう。

下は実行サンプルです。(注:読みやすくするために改行しています。)

DLしたデータを区別しやすいように、適当なディレクトリを作ってそのディレクトリ下で実行したほうがよいでしょう。


example

$ curl -Ls https://www.irasutoya.com/2015/11/blog-post_607.html | \

xmllint --html --xpath '//img/@src' - | \
xargs -n 1 | \
cut -d= -f2 | \
sed 's/^\/\//https:\/\//' | \
xargs -n 1 curl -L#O


ちょいと解説


curl

ご存知、Webページを取得するコマンド「カール」です。1

-L で、リダイレクト指示されてもリダイレクト先の情報を取るようにします。

-s で、インジケータ(進捗状況を表すメモリ)を出さないようにします。

-# は、インジケータではなく#で作られた進捗メーターが出ます。

-O は、ファイル出力です。ファイル名指定しないと、画像のファイル名を用いて保存します。


xmllint

XMLをパースするコマンドです。HTMLもパースできます。

--html で、htmlとみなしてパースします。

--xpath で、XPathを用いて部分的にデータを抽出します。

- は、データとして(パイプから渡された)標準入力を用いることを指します。


xargs

引数の最大値はOS依存ですが、限界があります。コマンド xargs は、主にパイプで与えられたデータを引数の列挙とみなし、コマンドを実行します。

ここでは、1行ずつ処理するために '-n' オプションを使っています。

xargs -n 1 は、コマンドが省略されているので、暗黙的に echo が実行されます。2

xargs -n 1 curl は、 curl ...1個目... curl ...2個目...と、順番にcurlが実行されます。


cut

ワンライナー使いの定番コマンドですな。

-dで示すデリミタで引数(主に文字列)を区切り、-f n で、n番目のものを抽出します(n,mn-mとかn- とかといった複数指定も可能)


sed

こちらもワンライナーなどでよく使われる、元祖正規表現置換コマンド。3

ここでは、URLが//で始まる場合に、https://にするよう置換しています。


エイリアス化

エイリアス(alias)化はできないです。URLとして引数を使うので。

なので手軽に使いたい場合は、.bashrc など、rcファイルに関数として登録するといいかもですね。


.bashrc

#関数サンプル(追加部分)

imgg() {
curl -Ls $1 | \
xmllint --html --xpath '//img/@src' - | \
xargs -n 1 | \
cut -d= -f2 | \
sed 's/^\/\//https:\/\//' | \
xargs -n 1 curl -L#O
}


使用上のご注意!


  • HTML内の<img> だけを抽出し、そのsrc属性を参照しています。cssで定義されている画像やJavascriptなどで動的に読み込んだ画像(例えばGoogleの検索結果ページのようなもの)には対応していません。改造すればいけるかもですが。

  • HTMLに構文的なエラーがある場合、標準エラー出力にxmllintのエラーが表示されますが、処理はそれを無視して進みます。

  • 短時間に大量にアクセスすると、対象のサーバに負荷がかかりますので、良識の範囲で使いましょう!

  • 画像やコンテンツには著作権があります。著作権を侵害しないように使いましょう!

(おわり)





  1. 長嶋茂雄氏の友達ではありません。 



  2. なお、 echo の引数として与えられた時に"〜"が展開されるようで、結果的にダブルクォーテーションマークが削除されます。 



  3. sedでの置換はPerlでも表現可能で、かつ正規表現の機能も多く、記述も楽(エスケープしなくて良い)。なので、sedは使われる機会が減った印象。なお、Perlの関数's///'はこのsedコマンドが由来。