非IT企業に勤める中年サラリーマンのIT日記

非IT企業でしかもITとは全く関係ない部署にいる中年エンジニア。唯一の趣味がプログラミングという”自称”プログラマー。

【Python】画像共有サイト(Pixabay)からカテゴリ指定で200枚一括ダウンロードする方法

   

画像共有サイト(Pixabay)からカテゴリを指定して画像200枚(もちろん枚数設定可能)を一括ダウンロードするプログラムを作成したので書き留めておきます。

事前準備:PixabayアカウントからAPIキー取得

PixabayはCloudflareによる強力なボット対策が施されているため、Webスクレイピング(HTMLの直接取得)を行うと403エラーでブロックされる可能性が高く、公式の無料APIを利用する方法が最も確実で安全です。

アカウントを持っていない場合は作成し、Pixabay API Documentation ページ(https://pixabay.com/api/docs/)にアクセスすると、以下のように自分の API Key が表示されます。メモしておきましょう。

 

Pythonプログラム

以下がダウンロードするPythonプログラムです。直下にpixabay_downloaded_images というフォルダが作成され、あらかじめ TARGET_COUNT 変数に設定している画像数分だけダウンロードしてくれます。

import os
import random
import time
import requests

# 1. Pixabay API Key
API_KEY = "YOUR_PIXABAY_API_KEY"

# 2. 検索条件の設定
QUERY = "technology programming dark workspace" # 画像のカテゴリ
TARGET_COUNT = 200 # ダウンロード数
OUTPUT_DIR = "pixabay_downloaded_images"  # 保存先フォルダ


def fetch_and_download_images(api_key, query, target_count=200, save_dir="images"):
  # 【ポイント1】保存先フォルダを確実に作成
  os.makedirs(save_dir, exist_ok=True)

  url = "https://pixabay.com/api/"
  params = {
      "key": api_key,
      "q": query,
      "image_type": "photo",
      "per_page": 200,
      "safesearch": "true",
  }

  print("APIリクエストを送信中...")
  response = requests.get(url, params=params)

  if response.status_code != 200:
    print(f"エラー: APIリクエストに失敗しました (Status Code: {response.status_code})")
    return

  data = response.json()
  hits = data.get("hits", [])

  if not hits:
    print("画像が見つかりませんでした。")
    return

  total_hits = len(hits)
  random.shuffle(hits)
  selected_hits = hits[: min(target_count, total_hits)]

  print(f"{len(selected_hits)} 枚の画像をダウンロード開始します...\n")

  for i, hit in enumerate(selected_hits, start=1):
    image_url = hit.get("largeImageURL") or hit.get("webformatURL")
    if not image_url:
      continue

    try:
      img_bytes = requests.get(image_url, timeout=15).content

      # 【ポイント2】ファイル名のみを指定(サブフォルダを含めない)
      filename = f"image_{i:03d}_{hit['id']}.jpg"

      # os.path.join でパスを正しく結合
      filepath = os.path.join(save_dir, filename)

      # 【ポイント3】念のため書き込み直前に対象ディレクトリの存在を補償
      os.makedirs(os.path.dirname(filepath), exist_ok=True)

      with open(filepath, "wb") as f:
        f.write(img_bytes)

      print(f"[{i}/{len(selected_hits)}] 保存完了: {filepath}")
      time.sleep(0.3)

    except Exception as e:
      print(f"[{i}/{len(selected_hits)}] ダウンロード失敗: {e}")

  print(f"\nダウンロード処理が完了しました。保存先: ./{save_dir}")


if __name__ == "__main__":
  fetch_and_download_images(API_KEY, QUERY, TARGET_COUNT, OUTPUT_DIR)
 

 

 

スポンサーリンク

 - Python