Python

【サンプルあり】PythonでWEB上の画像をダウンロードする方法

【サンプルあり】PythonでWEB上の画像をダウンロードする方法

WEBサイトが提供してくれている画像、ひとつずつダウンロードするの面倒くさい

WEB上には色々なファイルがアップロードされている。

どれも自由に使えるという訳ではないが、中には「常識の範囲でご自由にお使いください」として画像ファイルを提供してくれるサイトもある。

スタジオジブリも2020年9月から作品の場面写真の提供を開始している。

しかしひとつ問題が。

zipじゃないのね

そう、zipではなく1枚1枚提供されているのである。

1枚ずつだと全部手動でダウンロードするのは手間がかかる

ではどうすればいいのか。

Pythonでいけそうな気がする
無いならば
作ってしまえ
ホトトギス

ということで今回はPythonでWEB上の画像をダウンロードする方法について紹介する。

この記事を書いている人


システムエンジニア、AIエンジニアと、IT業界で10年以上働いている中堅。PythonとSQLが得意。

記事を読むメリット

PythonでWEB上の画像をダウンロードする方法がわかる


Pythonで画像取得できそうか確認

まずPythonで画像取得するにも、できそうな根拠が必要となる。

根拠を確認するポイントがURLだ。

画像ひとつひとつに振られているURLを機械的に取得、もしくは類推できると一括で画像取得できる可能性が高くなる。


画像URLの確認方法はChromeの場合は 画像右クリック→画像アドレスをコピー して、メモ帳でもWEBブラウザでもいいので取得したアドレス(URL)を貼り付けてみる。

Chrome 画像アドレスをコピー
Chrome 画像アドレスをコピー

得られた画像URLは以下の通り。

https://www.ghibli.jp/gallery/nausicaa001.jpg

URLの構造としては以下の法則で作られている模様。

https://www.ghibli.jp/gallery/ + {映画タイトル} + {連番3桁}

これなら映画タイトルの文字列さえわかってしまえばあとは機械的に連番で取得することができそうである。



PythonでWEB上の画像をダウンロードする方法

PythonでWEB上の画像をダウンロードするには、 requests でWEB上のコンテンツを取得し、 open()write()でローカル環境に書き込む。

順を追って作成していく。


step
1
1ファイルを取得

まず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に保存することができる。


画像がzipで提供されてなくてもPythonで一括取得できるものなんだね
これもスクレイピングの1つですね
Pythonを使うとWEB上から色々な情報を取得できるようになります
ただ機械的なデータ取得は相手側のサーバーに対して短時間にリクエストを多量に投げることになります。負荷をかけるのは良くないので連続で実行しないように注意しましょう



もしスクレイピングを定期的に実行したい場合、小型PCがあると運用機とメイン機を分離できて便利である。

オススメ小型PCや理由について記事にまとめたので、気になったら参考にしてほしい。

ITipsと同じようなブログを作る方法

ブログに興味がありますか?

もしブログに興味がある場合は↓このページ↓を参考にすれば、ITipsと同じ構成でブログを作ることができます

サーバー、ドメイン、ASPと【ブログに必要なものは全て】このページに書きました。
同じ構成でブログ作るのはいいけど、記事はマネしないでネ (TДT;)

ランキング参加中

にほんブログ村 IT技術ブログへ

他にもブログやSNSで紹介してくれると励みになります。

はてブのコメントで酷評されると泣きます(´;ω;`)

-Python
-

© 2024 ITips