のどあめ

ググってもなかなか出てこなかった情報を垂れ流すブログ。

Web画像検索で画像を収集する

沢山の画像を利用して何やらしたい時があります.
たいていはImageNetやFlickrで収集すれば良いのですが, 時には普通のWebで画像検索した結果を利用したいこともあります.

以前に,Web画像検索した結果を収集したい時の最適解はなんだろうと検討したことがありましたので, その結果をメモついでに記事にしました.

画像収集に利用するサービスの検討

Google画像検索API

制限が厳しくなり,同じクエリに対して10枚×10ページの合計100枚までしか取得できないようです. 画像を収集するという意味では使いにくいですね.

基本的な使い方は

Bing Search API

同じクエリでも1000件以上収集できます(上限は確認していません).
無料枠でも月5000回Getできるので画像収集として使えますね.
今回はBing Search APIが最適解という結論に至りました.

API利用までの流れなどは以下の記事で詳しく紹介されています.
Bing Search APIを使ってWeb検索を行うには(Json編) | garicchi.com

画像収集スクリプト(Python)

今回はWindowsで利用したのでcp932とか書いてますが, 違う環境の場合は適宜修正してください.

# coding: utf-8
import sys, os
import argparse
import json
import urllib
import urllib2
import requests

#proxy setting
proxy_dict =  {"http":"your.proxy:8080"}
proxy = urllib2.ProxyHandler(proxy_dict)
opener = urllib2.build_opener(proxy)
urllib2.install_opener(opener)

#primary account key
api_key="*************************************"

def download_urllist(urllist,outpath):
    for url in urllist:
        try:
            print"url:"+url
            with open(outpath+"/"+os.path.basename(url),'wb') as f:
                img=urllib2.urlopen(url,timeout=5).read()
                f.write(img)
        except urllib2.URLError:
            print("URLError")
        except IOError:
            print("IOError")
        except UnicodeEncodeError:
            print("EncodeError")
        except OSError:
            print("OSError")

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("-q","--query", required=True, 
            help="query")
    parser.add_argument("-o","--outpath", required=True,
            help="output path")
    args = parser.parse_args()


    #Bing Image Search
    query = args.query.decode('cp932').encode('utf-8')
    query = urllib2.quote(query)

    step = 20
    num = 50
    
    url_param_dict={
            "Query":"'%s'"%(query),
            "Market":"'ja-JP'",
            "Adult":"'Off'",
            }
    url_param_base = urllib.urlencode(url_param_dict)
    url_param_base = url_param_base + "&$format=json&$top=%d&$skip="%(num)


    for skip in range(0,num*step,num):
        url_param = url_param_base + str(skip)
        url="https://api.datamarket.azure.com/Bing/Search/Image?"+url_param
        print url

        response = requests.get(url, 
                            auth=(api_key, api_key), 
                            headers={'User-Agent': 'My API Robot'},
                            proxies=proxy_dict)
        response=response.json()

        urllist=[item['MediaUrl'] for item in response['d']['results']]
        download_urllist(urllist,args.outpath)

画像収集スクリプトは以下の記事を参考にしました.
Bing Search API を使いたいと思ったのでPythonでラッパーを作ってみた - [[ともっくす alloc] init]

使い方は

python collect_images.py -q Query -o outputdir

です.

-qで指定したクエリについて,step*num件の画像をダウンロードします.
ダウンロードした結果にはゴミも多いので,いい感じにクリーニングして利用しましょう.