WEB上には色々なファイルがアップロードされている。
どれも自由に使えるという訳ではないが、中には「常識の範囲でご自由にお使いください」として画像ファイルを提供してくれるサイトもある。
スタジオジブリも2020年9月から作品の場面写真の提供を開始している。
しかしひとつ問題が。
そう、zipではなく1枚1枚提供されているのである。
1枚ずつだと全部手動でダウンロードするのは手間がかかる。
ではどうすればいいのか。
作ってしまえ
ホトトギス
ということで今回はPythonでWEB上の画像をダウンロードする方法について紹介する。
この記事を書いている人
記事を読むメリット
PythonでWEB上の画像をダウンロードする方法がわかる
Pythonで画像取得できそうか確認
まずPythonで画像取得するにも、できそうな根拠が必要となる。
根拠を確認するポイントがURLだ。
画像ひとつひとつに振られているURLを機械的に取得、もしくは類推できると一括で画像取得できる可能性が高くなる。
画像URLの確認方法はChromeの場合は 画像右クリック→画像アドレスをコピー
して、メモ帳でもWEBブラウザでもいいので取得したアドレス(URL)を貼り付けてみる。
Chrome 画像アドレスをコピー |
---|
得られた画像URLは以下の通り。
URLの構造としては以下の法則で作られている模様。
https://www.ghibli.jp/gallery/ + {映画タイトル} + {連番3桁}
これなら映画タイトルの文字列さえわかってしまえばあとは機械的に連番で取得することができそうである。
PythonでWEB上の画像をダウンロードする方法
PythonでWEB上の画像をダウンロードするには、 requests
でWEB上のコンテンツを取得し、 open()
とwrite()
でローカル環境に書き込む。
順を追って作成していく。
step
11ファイルを取得
まず1ファイルだけ取得するなら以下のようなコードとなる。
image_dl_v0.1.py
import requests url = "https://www.ghibli.jp/gallery/nausicaa001.jpg" file_name = "nausicaa001.jpg" response = requests.get(url) image = response.content with open(file_name, "wb") as f: f.write(image)
これを実行すると1つの画像ファイルを保存できる。
step
2複数ファイル取得
では複数ファイルを保存するにはどうするか。
001
などの連番3桁の部分を動的に作ってそれぞれの画像ファイルを取得すると複数ファイル取得できる。
image_dl_v0.2.py
import requests # 1から100までの画像を取得する for i in range(1,100): print(i) url = "https://www.ghibli.jp/gallery/nausicaa{}.jpg".format(str(i).zfill(3)) file_name = "ghibli/nausicaa{}.jpg".format(str(i).zfill(3)) response = requests.get(url) image = response.content with open(file_name, "wb") as f: f.write(image)
ここではゼロ埋めして3桁の数字を作るので zfill()
を使っている。
あわせて読みたい
step
3余計な範囲まで取得しないようにする
しかし問題が1つあって、画像は100枚あるわけではない。
例えば40枚しかなければ41以降は空の画像ファイルができてしまう。
これを防ぐためにURLにアクセスした際のレスポンスコードをチェックする。
正常に取得できた場合はレスポンスに 200
を返すので、それ以外の値が帰ってきたら以降のループを終了するようにする。
response = requests.get(url) # 画像を取得できない番号が出てきたらループ終了 if response.status_code != 200: print("エラーが起こりました。ステータスコード: " + str(response.status_code) + "\n" + url) break image = response.content
step
4他のタイトルも取得できるようにする
あとは {映画タイトル}
のアルファベットを確認すれば全ての画像を取得できる。
タイトルのlist形式で持たせ、リストの要素毎に実行するようにすれば完成。
image_dl.py
import requests title_list = [ "nausicaa", "red-turtle", "onyourmark", "omoide", "laputa", "tanuki", "umi", "porco", "majo", "totoro", "howl", "baron", "ghiblies", "yamada", "mononoke", "mimi", "ged", "chihiro", "ponyo", "karigurashi", "kokurikozaka", "kazetachinu", "kaguyahime", "marnie", ] for title in title_list: print(title) for i in range(1,100): print(i) url = "https://www.ghibli.jp/gallery/{}{}.jpg".format(title,str(i).zfill(3)) file_name = "ghibli/{}{}.jpg".format(title,str(i).zfill(3)) response = requests.get(url) # 画像を取得できない番号が出てきたらループ終了 if response.status_code != 200: print("エラーが起こりました。ステータスコード: " + str(response.status_code) + "\n" + url) break image = response.content with open(file_name, "wb") as f: f.write(image)
これで1000枚を超える画像を取得できるようになった。
まとめ
今回はPythonでWEB上の画像をダウンロードする方法についてスタジオジブリの画像を例にして紹介した。
WEB上の画像をダウンロードするには、まず対象のページを観察し、画像URLが機械的に取得・類推できるか確認する。
そして画像URLがが取得可能であれば、 requests
を使ってコンテンツを取得し、 open()
, write()
でローカルPCに保存することができる。
もしスクレイピングを定期的に実行したい場合、小型PCがあると運用機とメイン機を分離できて便利である。
オススメ小型PCや理由について記事にまとめたので、気になったら参考にしてほしい。