【Azure】Azure Bing APIで画像を取得する

こんにちは、エピックです。

AIのモデル学習に必要となる画像の収集方法のうち、Bingから画像を取得する方法を試してみたので紹介したいと思います。

Azureを使っていくのでコストには注意です。

目次

事前準備 APIの有効化

Bing API の利用には、Microsoftアカウントの作成および Azureポータル上からの Bing Search APIs の有効化が必要となります。

クレジットカードの登録が必要となるため注意してください。

また、利用料はAPIを叩くたびに発生する点にもちゅういます。

登録手順は下記を参考にしてみてください

Quita「Bingの画像検索APIを使って画像を大量に収集する」

コードを書く

実行コードは python となります。

import os
import math
import requests
import urllib.parse
from urllib import parse


def make_directory(path):
    if not os.path.exists(path):
        os.mkdir(path)


def create_image_path(path, search_word, url, serial_number_of_iamges):
    serial_number_of_iamges += 1
    file_extention = os.path.splitext(url)[-1]
    if file_extention.lower() in (".jpg", ".jpeg", ".png"):
        path_of_image = os.path.join(
            path, str(serial_number_of_iamges) + "_" + search_word + file_extention)
        return path_of_image
    else:
        raise ValueError("Not Applicable file extension")


def search_image(params, api_key):
    bing_image_search_endpoint = "https://api.cognitive.microsoft.com/bing/v7.0/images/search"
    headers = {"Ocp-Apim-Subscription-Key": api_key}
    response = requests.get(bing_image_search_endpoint,
                            headers=headers,
                            params=params)
    response.raise_for_status()
    return response


def creat_image_url_list_per_search_word(search_word, api_key, need_image_num, get_image_count=30):

    offset_count = math.floor(need_image_num / get_image_count)

    image_url_list_per_search_word = []

    for offset in range(offset_count):

        # count:1トランザクションで取得する画像数
        # offset:スキップする結果の数
        params = urllib.parse.urlencode({'q': search_word, 'count': get_image_count,
                                         'offset': offset*get_image_count})
        try:
            res = search_image(params=params, api_key=api_key)
            response_json = res.json()
        except Exception as err:
            print("例外args:", err.args)
        else:
            for values in response_json['value']:
                image_url_list_per_search_word.append(
                    parse.unquote(values["contentUrl"]))

    return image_url_list_per_search_word


def get_image_binary_from_url(_image_url):
    response_from_image_url = requests.get(_image_url, timeout=10)

    if response_from_image_url.status_code != 200:
        error = Exception("HTTP status code: " +
                          str(response_from_image_url.status_code))
        raise error
    content_type = response_from_image_url.headers['content-type']
    if "image" not in content_type:
        error = Exception("Content-Type: " + content_type)
        raise error

    return response_from_image_url.content


def save_image(file_path, image):
    with open(file_path, "wb") as f:
        f.write(image)


if __name__ == "__main__":
    make_directory("data")

    """
    Before execute, you need to export apikey
    Ex.
    export AZURE_BING_SEARCH_API_KEY=your_key
    """
    BING_API_KEY = os.getenv("AZURE_BING_SEARCH_API_KEY")

    # 取得したい画像のワード ex. ザク
    SEARCH_WORD = "ザク"
    SAVE_IMAGE_DIR = os.path.abspath("data")

    # 必要な画像枚数 Min: 30
    GET_IMAGE_NUMBER = 30

    # 取得画像のプリフェックス
    serial_number_of_iamges = 0

    save_directory = os.path.join(SAVE_IMAGE_DIR, SEARCH_WORD)
    make_directory(save_directory)

    image_url_list = creat_image_url_list_per_search_word(
        SEARCH_WORD, BING_API_KEY, GET_IMAGE_NUMBER)

    for image_url in image_url_list:  
        try:
            image_content = get_image_binary_from_url(image_url)
            full_path_to_image = create_image_path(
                save_directory, SEARCH_WORD, image_url, serial_number_of_iamges)
            save_image(file_path=full_path_to_image,
                       image=image_content)
            print("Saved image file: ", full_path_to_image)
            serial_number_of_iamges += 1
        except KeyboardInterrupt:
            break
        except Exception as err:
            print(err)

    print("Success!")

実行の際ですが、APIキーの環境変数への設定を事前に行ってください。

例えば、Macの環境であれば下記をターミナル上へ入力します。

export AZURE_BING_SEARCH_API_KEY=<your_key>

最後に

今回は、BIngのAPIを利用してみました。
コードについては、少し勉強が必要でしたがリファレンスが丁寧であったのでとくに苦労せず作成することができました。
画像の取得をするようになって思うのは、最近はどこもクローリングができませんね。

その点で、多少の金額は発生しますが画像を取得することができるBingの存在はありがたいです。

最後までお読みいただきありがとうございました。

コード上や実行上で不明点等あればコメントいただければと思います。

では。

目次