目的
PythonとGoogleカスタム検索APIを利用した画像ファイルのダウンロードを試してみました。
キーワードに一致する画像をダウンロードします。
実装方法は https://blog.aidemy.net/entry/2017/12/17/214715 を参考にさせて頂きました。
参考
【顔分類その1】PythonとGoogleカスタム検索APIを利用した画像ダウンロード
【顔分類その2】PythonとOpenCVを利用した画像ファイルからの顔の切り出し
【顔分類その3】PythonとOpenCVを利用した画像ファイルの水増し
【顔分類その4】Pythonとkerasを利用した顔分類モデルの生成
【顔分類その5】Pythonとkerasを利用して本田翼か佐倉綾音かを分類
【顔分類その6】Djangoとkerasを利用した本田翼か佐倉綾音かを分類するWebアプリ
環境
- Windows 10 x64 1809
- Python 3.6.5 x64
- Power Shell 6 x64
- Visual Studio Code x64
- Git for Windows x64
Custom Search API の有効化とキーの取得
-
Google Cloud Platform にログインし、新しいプロジェクトを作成します。
-
作成したプロジェクトのダッシュボードにある「APIとサービスを有効化」をクリックします。
-
「APIサービス」で「Custom Search API」を検索してクリックします。
-
「Custom Search API」が有効であることを確認して「管理」をクリックします。
-
「Custom Search API」の管理で「認証情報」をクリックします。
-
「認証情報」でAPIのキーをコピーします。(このキーをあとで利用します。)
画像の検索エンジンの作成
-
カスタム検索エンジンにログインし、検索エンジンを追加します。
-
「検索するサイト」にwww.google.co.jpを入力、「言語」を選択、「検索エンジンの名前」を入力して「作成」をクリックします。(「検索するサイト」はあとで削除しますので任意のURLで構いません)
-
作成した検索エンジンを編集します。
-
「検索エンジン ID」をコピーします。(このIDをあとで利用します。)
-
「検索するサイト」を削除し、「画像検索」をON、「ウェブ全体を検索」をONにして「更新」をクリックします。
環境構築
-
Windows 10 x64 に Python 3.6.x x64 をインストールします。
-
環境変数の PATH に、インストールしたPythonのフォルダとPython\Scriptsフォルダを設定しておきます。
-
下記手順で Python の仮想環境を構築し、有効化してpipをアップデートします。
> python -m venv venv
> .\venv\Scripts\activate.ps1
(venv)> python -m pip install --upgrade pip
- pip でいろいろインストールします。
(venv)> pip install pylint
(venv)> pip install requests
(venv)> pip install python-dotenv
(venv)> pip install google-api-python-client
- Google API を利用するためのキーとIDを設定した.envファイルを作成します。
事前にコピーしたキーとIDを設定します。
# API KEY
API_KEY = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
# 検索エンジンID
CUSTOM_SEARCH_ENGINE = "000000000000000000000:XXXXXXXXXXX"
プログラム作成
-
画像をダウンロードするプログラムを Python で書きます。
-
ファイル名は「img_dl_gcs.py」とします。
import os
import sys
from urllib.parse import quote
import requests
import settings
# 指定したキーワードで検索した画像のURLを取得
def get_image_urls(keyword, total_num):
image_urls = []
i = 0
while i < total_num:
# クエリの組み立て
query = CUSTOM_SEARCH_URL + "?key=" + settings.API_KEY + \
"&cx=" + settings.CUSTOM_SEARCH_ENGINE + "&num=" + \
str(10 if(total_num-i) > 10 else (total_num-i)) + "&start=" + \
str(i+1) + "&q=" + quote(keyword) + "&searchType=image"
print(query)
# GETリクエスト
response = requests.get(query)
# JSONデータ取得
json = response.json()
# 10件ずつのURLを格納
for j in range(len(json["items"])):
image_urls.append(json["items"][j]["link"])
i = i + 10
return image_urls
# 画像のURLをもとに画像をダウンロードして保存
def get_image_files(dir_path, keyword_count, image_urls):
# 画像urlループ
for (idx, image_url) in enumerate(image_urls):
try:
# 画像をダウンロード
print(image_url)
image = download_image(image_url)
# ファイル名を作成
filename_extension_pair = os.path.splitext(image_url)
extension = filename_extension_pair[1]
extension = extension if len(extension) <= 4 else extension[0:4]
filename = os.path.join(dir_path, f"{keyword_count:02}_{idx+1:03}{extension}")
print(filename)
# 画像をファイルとして保存
save_image(filename, image)
except RuntimeError as ex:
print(f"type:{type(ex)}")
print(f"args:{ex.args}")
print(f"{ex}")
continue
except BaseException as ex:
print(f"type:{type(ex)}")
print(f"args:{ex.args}")
print(f"{ex}")
continue
# 画像をダウンロード
def download_image(url):
response = requests.get(url, timeout=100)
if response.status_code != 200:
raise RuntimeError("画像が取得できません")
content_type = response.headers["content-type"]
if 'image' not in content_type:
raise RuntimeError("画像ではありません")
return response.content
# 画像をファイルとして保存
def save_image(filename, image):
with open(filename, "wb") as file:
file.write(image)
# ディレクトリまたはディレクトリ内のファイル削除
def delete_dir(dir_path, is_delete_top_dir=True):
for root, dirs, files in os.walk(dir_path, topdown=False):
for name in files:
os.remove(os.path.join(root, name))
for name in dirs:
os.rmdir(os.path.join(root, name))
if is_delete_top_dir:
os.rmdir(dir_path)
RETURN_SUCCESS = 0
RETURN_FAILURE = -1
# Custom Search Url
CUSTOM_SEARCH_URL = "https://www.googleapis.com/customsearch/v1"
# Download Directory Path
ORIGIN_IMAGE_DIR = "./origin_image"
def main():
print("===================================================================")
print("イメージダウンローダー Google Customr Search API 版")
print("指定したキーワードで検索した画像ファイルをダウンロードします。")
print("===================================================================")
# 引数のチェック
argvs = sys.argv
if len(argvs) != 2 or not argvs[1]:
print("キーワードを指定してください。(カンマ区切り可能)")
return RETURN_FAILURE
# キーワードの取得
keywords = [x.strip() for x in argvs[1].split(',')]
# ディレクトリの作成
if not os.path.isdir(ORIGIN_IMAGE_DIR):
os.mkdir(ORIGIN_IMAGE_DIR)
delete_dir(ORIGIN_IMAGE_DIR, False)
# キーワードごとに画像ファイル取得
keyword_count = 1
for keyword in keywords:
# キーワード表示
print(f"キーワード「{keyword}」で検索した画像ファイルをダウンロードします。")
# 画像URL取得
image_urls = get_image_urls(keyword, 100)
# 画像ファイルのダウンロード
get_image_files(ORIGIN_IMAGE_DIR, keyword_count, image_urls)
# カウントアップ
keyword_count = keyword_count + 1
return RETURN_SUCCESS
if __name__ == "__main__":
main()
-
設定ファイルを読み込むプログラムを Python で書きます。
-
ファイル名は「settings.py」とします。
import os
from os.path import join, dirname
from dotenv import load_dotenv
dotenv_path = join(dirname(__file__), '.env')
load_dotenv(dotenv_path)
API_KEY = os.environ.get("API_KEY")
CUSTOM_SEARCH_ENGINE = os.environ.get("CUSTOM_SEARCH_ENGINE")
プログラム実行
- 検索するキーワードを指定して実行します。
(venv)> python img_dl_gcs.py あのひと,このひと
- origin_imageフォルダにダウンロードした画像が保存されます。
拡張子を特定できないファイルも関係なくダウンロードされます。
最後に
深層学習で画像の分類を行いたいという勢いから、いろいろな情報を参考にやってみました。
Google の Custom Search API は検索数の制限がありますので、ダウンロード数の上限を100枚としています。