Bing + Python、画像検索

Bing + Python 既存のセットなどから適切なトピックを選択できるように、特定のトピックに関する写真を収集する必要がある場合があります。 現在の検索エンジンはそのような機会を提供しますが、ブラウザを開き、ページをナビゲートし、マウスで作業し、一般的にはそれを行う必要があります。 必要な画像のセットに対して、コンソールユーティリティを「実行して忘れる」ようにしたいと思います。 Bing API、Pythonでの開始、および画像検索のためのそれらの組み合わせを検討します。


はじめに


これは、最近研究を始めた多かれ少なかれ私の最初のPythonプログラムです(ちなみに、彼の記事の翻訳についてはkossmakに感謝します )。 記事の最後での使用例。

TK


検索文字列と必要な数の画像を入力として受け入れるコンソールプログラム。 出力は、検索結果を含む現在のサブディレクトリにあります。

なぜビンビン


少し前に、ActionScriptで非同期ローダーをテストする必要がありました。 ロードにGoogleが選択されましたが、結果として、APIを介したリクエストに対してGoogleが生成する結果は64個以下であることが判明しました。 これは(当時)十分でしたが、堆積物は残りました。 検索後、見つかったのは、Yahoo(提供するデータの多くが古くなっているというコメント付き)とBing(ページ上で最大1000件の結果が約束されている)です。 Bingが選択された理由は、リクエスト自体に加えて、リクエストにフィルターを課すことができるためです(以下を参照)

ビング


Bing開発は、 Bing Developer Centerページから始まります。 各リクエストに署名するにはAPP_IDを取得する必要があります。登録はわずかです。 課された制限を本当に理解していなかったので(存在しないかもしれません)、テストAPP_IDを例とともに公開します(使用する場合は、APP_IDをコードに追加して駆動することをお勧めします)。

Bing API


VB / C#/ C ++ / F#/ JS用のAPIが存在しますが、この例では最後のhttpリクエストを使用しています。 画像検索用APIの説明はこちら
したがって、JSON形式の写真と応答を検索するための最小限のクエリは次のようになります。
api.search.live.net/json.aspx?appid=APP_ID&sources=image&query=SEARCH_QUERY
リクエストの例(リンゴの検索):
http://api.search.live.net/json.aspx?appid=4EFC2F2CA1F9547B3C048B40C33A6A4FEF1FAF3B&sources=image&query=apple

Python


すべてがシンプルでクロスプラットフォームです。 Python自体(バージョン2.6.x)はここから配置されます 。 開発環境として、私はPyDevが本当に好きでした。 Eclipseを配置し(まだない場合)、そこからPyDevを配置します

アルゴリズム


私はブロックごとにコメントしません、コードには多くのコメントがあります;さらに、それは1つのブロックに入れないほど大きくはありません。 簡単に:


コード


# import used libraries
import urllib , json , sys , os , threading

def load_url (url, filename, filesystem_lock):
try :
# open connection to URL
socket = urllib . urlopen(url)
# read data
data = socket . read()
# close connection
socket . close()
# on all exceptions
except :
print "error loading" , url
# if no exceptions
else :
# save loaded data
save_to_file(data, filename, filesystem_lock)

def save_to_file (data, filename, filesystem_lock):
# wait for file system and block it
filesystem_lock . acquire()
try :
# while already have file with this name
while os . path . isfile(filename):
# append '_' to the beginning of file name
filename = os . path . dirname(filename) + "/_" + os . path . basename(filename)
# open for binary writing
with open (filename, 'wb' ) as f:
# and save data
f . write(data)
f . close()
print filename
except :
print "error saving" , filename
# release file system
filesystem_lock . release()

def main ():
# Bing search URL
SERVICE_URL = "http://api.search.live.net/json.aspx"
# request parameters dictionary (will append to SERVICE_URL)
params = {}
params[ "appid" ] = "4EFC2F2CA1F9547B3C048B40C33A6A4FEF1FAF3B"
params[ "sources" ] = "image"
params[ "image.count" ] = 8
params[ "image.offset" ] = 00

# try to read command line parameters
try :
params[ "query" ] = sys . argv[ 1 ]
images_count = int (sys . argv[ 2 ])
if len (sys . argv) > 3 :
params[ "image.filters" ] = sys . argv[ 3 ]
# if have less than 2 parameters (IndexError) or
# if second parameter cannot be cast to int (ValueError)
except ( IndexError , ValueError ):
# print usage string
print "Bing image search tool"
print "Usage: bing.py search_str images_count [filters]"
# end exit
return 1

# make directory at current path
dir_name = "./" + params[ "query" ] + "/"
if not os . path . isdir(dir_name):
os . mkdir(dir_name)

# list to store loading threads
loaders = []
# file system lock object
filesystem_lock = threading . Lock()

try :

# loop for images count
while (params[ "image.offset" ] < images_count):

# combine URL string, open it and parse with JSON
response = json . load(urllib . urlopen(SERVICE_URL + "? %s " % urllib . urlencode(params)))
# extract image section
images_section = response[ "SearchResponse" ][ "Image" ]

# if current search offset greater or equal to returned total files
if "Total" not in images_section or params[ "image.offset" ] >= images_section[ "Total" ]:
# then break search loop
break

# extract image results section
results = images_section[ "Results" ]
# loop for results
for result in results:
# extract image URL
image_url = result[ "MediaUrl" ]
# create new loading thread
loader = threading . Thread(\
target = load_url,\
args = (\
image_url,\
dir_name + os . path . basename(str(image_url)),\
filesystem_lock))
# start loading thread
loader . start()
# and add it to loaders list
loaders . append(loader)
# advance search offset
params[ "image.offset" ] += 1
# break if no more images needed
if params[ "image.offset" ] >= images_count:
break ;

# on all exceptions
except :
print "error occured"
return 1

# wait for all loading threads to complete
for loader in loaders:
loader . join()

# all done
print "done"
return 0 ;

if __name__ == '__main__' :
status = main()
sys . exit(status)

リクエスト例


リクエストを絞り込むには、スペースで区切ってBing APIフィルターを使用できます。

win32での単一のEXEの作成


これを行うには、py2exeが必要になります。 こちらからインストールできます 。 さらに、プログラムのあるフォルダーに、次の内容でsetup.pyファイルが作成されます(bing.pyファイル内のプログラム)。
from distutils.core import setup
import py2exe , sys , os

sys . argv . append( 'py2exe' )

setup(
console = [ 'bing.py' ],
options = { 'py2exe' : { 'bundle_files' : 1 }},
zipfile = None ,
)

また、コマンド「python setup.py」によって起動されます。 実行の結果、「コンパイル済み」プログラムが./distフォルダーに表示されます(w9xpopen.exeファイルは削除できます)
さらに、 UPXでシェイクできます (5182Kbから4061Kbになりました)

改善したいこと



PS


奇妙なHabrグリッチ。
<code><font color="#666666">0</font></code>
何も表示しません。
リンクも見る
<code>http://api.google.com</code>
httpなしで表示://

PPS


Win32用のコンパイル済みexeはこちら

Source: https://habr.com/ru/post/J91012/


All Articles