Python SDKを使ってImage Searchの類似検索を試す【検索編】

# 今回の目的（Python SDKを使って検索してみる）
前回、Image Searchの設定と画像取り込みまで終わりました。今回は、前回作ったImage Searchにプログラムでアクセスしてみようと思います。

## 実装環境の構築
今回はPoetryを使ってでプロジェクト作成します。Python、Poetryの開発環境が整っていない方はインストールを行っておいてください。

参考：Windows+Scoopの場合

```
PS C:\Users\user> pip install poetry
Collecting poetry
  Downloading https://files.pythonhosted.org/packages/19/52/ffdd04d17616cbfa47e0c145d0df2d1cf4280015c39db0a055fbfb06a8e2/poetry-1.0.5-py2.py3-none-any.whl (220kB)
     |████████████████████████████████| 225kB 3.3MB/s
Collecting clikit<0.5.0,>=0.4.2 (from poetry)
  Downloading https://files.pythonhosted.org/packages/7a/45/91c67a4f623bd09e98fe72c01e0139a9ae70bffdd658dce12e4a8be3c1e3/clikit-0.4.3-py2.py3-none-any.whl (88kB)
     |████████████████████████████████| 92kB 6.1MB/s
Collecting tomlkit<0.6.0,>=0.5.11 (from poetry)
  Downloading https://files.pythonhosted.org/packages/7d/8c/c3ee9cd41b2df781b2dc39c31209724b4f04a3110b46531de2e661ace186/tomlkit-0.5.11-py2.py3-none-any.whl
Collecting requests-toolbelt<0.9.0,>=0.8.0 (from poetry)
  Downloading https://files.pythonhosted.org/packages/97/8a/d710f792d6f6ecc089c5e55b66e66c3f2f35516a1ede5a8f54c13350ffb0/requests_toolbelt-0.8.0-py2.py3-none-any.whl (54kB)
     |████████████████████████████████| 61kB ...
Collecting shellingham<2.0,>=1.1 (from poetry)
  Downloading https://files.pythonhosted.org/packages/9f/6b/160e80c5386f7820f0a9919cc9a14e5aef2953dc477f0d5ddf3f4f2b62d0/shellingham-1.3.2-py2.py3-none-any.whl
Collecting pyparsing<3.0,>=2.2 (from poetry)
  Downloading https://files.pythonhosted.org/packages/8a/bb/488841f56197b13700afd5658fc279a2025a39e22449b7cf29864669b15d/pyparsing-2.4.7-py2.py3-none-any.whl (67kB)
     |████████████████████████████████| 71kB 4.5MB/s
Collecting keyring<21.0.0,>=20.0.1; python_version >= "3.5" and python_version < "4.0" (from poetry)
  Downloading https://files.pythonhosted.org/packages/f1/07/0afb82d449d210a332d126978634470abdd0c754128a9ead8bbe78eb1b43/keyring-20.0.1-py2.py3-none-any.whl
Collecting html5lib<2.0,>=1.0 (from poetry)
  Downloading https://files.pythonhosted.org/packages/a5/62/bbd2be0e7943ec8504b517e62bab011b4946e1258842bc159e5dfde15b96/html5lib-1.0.1-py2.py3-none-any.whl (117kB)
     |████████████████████████████████| 122kB 6.8MB/s
Collecting pkginfo<2.0,>=1.4 (from poetry)
  Downloading https://files.pythonhosted.org/packages/e6/d5/451b913307b478c49eb29084916639dc53a88489b993530fed0a66bab8b9/pkginfo-1.5.0.1-py2.py3-none-any.whl
Collecting cleo<0.8.0,>=0.7.6 (from poetry)
  Downloading https://files.pythonhosted.org/packages/4b/9d/10a5923c14c4f0faa98216af5262938f468af76101d9cd124ad2054943c7/cleo-0.7.6-py2.py3-none-any.whl
Collecting pexpect<5.0.0,>=4.7.0 (from poetry)
  Downloading https://files.pythonhosted.org/packages/39/7b/88dbb785881c28a102619d46423cb853b46dbccc70d3ac362d99773a78ce/pexpect-4.8.0-py2.py3-none-any.whl (59kB)
     |████████████████████████████████| 61kB 1.9MB/s
Collecting pyrsistent<0.15.0,>=0.14.2 (from poetry)
  Downloading https://files.pythonhosted.org/packages/8c/46/4e93ab8a379d7efe93f20a0fb8a27bdfe88942cc954ab0210c3164e783e0/pyrsistent-0.14.11.tar.gz (104kB)
     |████████████████████████████████| 112kB 3.3MB/s
Collecting jsonschema<4.0,>=3.1 (from poetry)
  Downloading https://files.pythonhosted.org/packages/c5/8f/51e89ce52a085483359217bc72cdbf6e75ee595d5b1d4b5ade40c7e018b8/jsonschema-3.2.0-py2.py3-none-any.whl (56kB)
     |████████████████████████████████| 61kB 3.8MB/s
Collecting cachecontrol[filecache]<0.13.0,>=0.12.4 (from poetry)
  Downloading https://files.pythonhosted.org/packages/18/71/0a9df4206a5dc5ae7609c41efddab2270a2c1ff61d39de7591dc7302ef89/CacheControl-0.12.6-py2.py3-none-any.whl
Collecting cachy<0.4.0,>=0.3.0 (from poetry)
  Downloading https://files.pythonhosted.org/packages/82/e6/badd9af6feee43e76c3445b2621a60d3d99fe0e33fffa8df43590212ea63/cachy-0.3.0-py2.py3-none-any.whl
Collecting requests<3.0,>=2.18 (from poetry)
  Downloading https://files.pythonhosted.org/packages/1a/70/1935c770cb3be6e3a8b78ced23d7e0f3b187f5cbfab4749523ed65d7c9b1/requests-2.23.0-py2.py3-none-any.whl (58kB)
     |████████████████████████████████| 61kB 3.8MB/s
Collecting pastel<0.3.0,>=0.2.0 (from clikit<0.5.0,>=0.4.2->poetry)
  Downloading https://files.pythonhosted.org/packages/06/cd/999508cef5e92fea672a420e3164bb02c01a763d5d6d5149312194c9178c/pastel-0.2.0-py2.py3-none-any.whl
Collecting pylev<2.0,>=1.3 (from clikit<0.5.0,>=0.4.2->poetry)
  Downloading https://files.pythonhosted.org/packages/40/1c/7dff1d242bf1e19f9c6202f0ba4e6fd18cc7ecb8bc85b17b2d16c806e228/pylev-1.3.0-py2.py3-none-any.whl
Collecting pywin32-ctypes!=0.1.0,!=0.1.1; sys_platform == "win32" (from keyring<21.0.0,>=20.0.1; python_version >= "3.5" and python_version < "4.0"->poetry)
  Downloading https://files.pythonhosted.org/packages/9e/4b/3ab2720f1fa4b4bc924ef1932b842edf10007e4547ea8157b0b9fc78599a/pywin32_ctypes-0.2.0-py2.py3-none-any.whl
Collecting six>=1.9 (from html5lib<2.0,>=1.0->poetry)
  Downloading https://files.pythonhosted.org/packages/65/eb/1f97cb97bfc2390a276969c6fae16075da282f5058082d4cb10c6c5c1dba/six-1.14.0-py2.py3-none-any.whl
Collecting webencodings (from html5lib<2.0,>=1.0->poetry)
  Downloading https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl
Collecting ptyprocess>=0.5 (from pexpect<5.0.0,>=4.7.0->poetry)
  Downloading https://files.pythonhosted.org/packages/d1/29/605c2cc68a9992d18dada28206eeada56ea4bd07a239669da41674648b6f/ptyprocess-0.6.0-py2.py3-none-any.whl
Requirement already satisfied: setuptools in c:\users\user\scoop\apps\python\3.8.2\lib\site-packages (from jsonschema<4.0,>=3.1->poetry) (41.2.0)
Collecting attrs>=17.4.0 (from jsonschema<4.0,>=3.1->poetry)
  Downloading https://files.pythonhosted.org/packages/a2/db/4313ab3be961f7a763066401fb77f7748373b6094076ae2bda2806988af6/attrs-19.3.0-py2.py3-none-any.whl
Collecting msgpack>=0.5.2 (from cachecontrol[filecache]<0.13.0,>=0.12.4->poetry)
  Downloading https://files.pythonhosted.org/packages/54/df/51af837ceaeda25563c99e13f772859784dd64fe6add68bfeade022b6aee/msgpack-1.0.0-cp38-cp38-win_amd64.whl (73kB)
     |████████████████████████████████| 81kB 5.1MB/s
Collecting lockfile>=0.9; extra == "filecache" (from cachecontrol[filecache]<0.13.0,>=0.12.4->poetry)
  Downloading https://files.pythonhosted.org/packages/c8/22/9460e311f340cb62d26a38c419b1381b8593b0bb6b5d1f056938b086d362/lockfile-0.12.2-py2.py3-none-any.whl
Collecting idna<3,>=2.5 (from requests<3.0,>=2.18->poetry)
  Downloading https://files.pythonhosted.org/packages/89/e3/afebe61c546d18fb1709a61bee788254b40e736cff7271c7de5de2dc4128/idna-2.9-py2.py3-none-any.whl (58kB)
     |████████████████████████████████| 61kB 3.8MB/s
Collecting certifi>=2017.4.17 (from requests<3.0,>=2.18->poetry)
  Downloading https://files.pythonhosted.org/packages/57/2b/26e37a4b034800c960a00c4e1b3d9ca5d7014e983e6e729e33ea2f36426c/certifi-2020.4.5.1-py2.py3-none-any.whl (157kB)
     |████████████████████████████████| 163kB ...
Collecting chardet<4,>=3.0.2 (from requests<3.0,>=2.18->poetry)
  Downloading https://files.pythonhosted.org/packages/bc/a9/01ffebfb562e4274b6487b4bb1ddec7ca55ec7510b22e4c51f14098443b8/chardet-3.0.4-py2.py3-none-any.whl (133kB)
     |████████████████████████████████| 143kB 6.4MB/s
Collecting urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 (from requests<3.0,>=2.18->poetry)
  Downloading https://files.pythonhosted.org/packages/e1/e5/df302e8017440f111c11cc41a6b432838672f5a70aa29227bf58149dc72f/urllib3-1.25.9-py2.py3-none-any.whl (126kB)
     |████████████████████████████████| 133kB 6.4MB/s
Installing collected packages: pastel, pylev, clikit, tomlkit, idna, certifi, chardet, urllib3, requests, requests-toolbelt, shellingham, pyparsing, pywin32-ctypes, keyring, six, webencodings, html5lib, pkginfo, cleo, ptyprocess, pexpect, pyrsistent, attrs, jsonschema, msgpack, lockfile, cachecontrol, cachy, poetry
  WARNING: The script chardetect.exe is installed in 'c:\users\user\scoop\apps\python\3.8.2\Scripts' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
  WARNING: The script keyring.exe is installed in 'c:\users\user\scoop\apps\python\3.8.2\Scripts' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
  WARNING: The script pkginfo.exe is installed in 'c:\users\user\scoop\apps\python\3.8.2\Scripts' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
  Running setup.py install for pyrsistent ... done
  WARNING: The script jsonschema.exe is installed in 'c:\users\user\scoop\apps\python\3.8.2\Scripts' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
  WARNING: The script doesitcache.exe is installed in 'c:\users\user\scoop\apps\python\3.8.2\Scripts' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
  WARNING: The script poetry.exe is installed in 'c:\users\user\scoop\apps\python\3.8.2\Scripts' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed attrs-19.3.0 cachecontrol-0.12.6 cachy-0.3.0 certifi-2020.4.5.1 chardet-3.0.4 cleo-0.7.6 clikit-0.4.3 html5lib-1.0.1 idna-2.9 jsonschema-3.2.0 keyring-20.0.1 lockfile-0.12.2 msgpack-1.0.0 pastel-0.2.0 pexpect-4.8.0 pkginfo-1.5.0.1 poetry-1.0.5 ptyprocess-0.6.0 pylev-1.3.0 pyparsing-2.4.7 pyrsistent-0.14.11 pywin32-ctypes-0.2.0 requests-2.23.0 requests-toolbelt-0.8.0 shellingham-1.3.2 six-1.14.0 tomlkit-0.5.11 urllib3-1.25.9 webencodings-0.5.1
WARNING: You are using pip version 19.2.3, however version 20.1 is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.

```

## Python プロジェクトの作成
それでは、Pythonのプロジェクトを作ってみましょう

Python プロジェクトの作成

```
PS C:\Users\user\Documents\py-sample> poetry new sample
Created package sample in sample
PS C:\Users\user\Documents\py-sample> ls


    Directory: C:\Users\user\Documents\py-sample

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----          2020/05/14    16:34                sample

PS C:\Users\user\Documents\py-sample> cd .\sample\
PS C:\Users\user\Documents\py-sample\sample> ls


    Directory: C:\Users\user\Documents\py-sample\sample

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----          2020/05/14    16:34                sample
d----          2020/05/14    16:34                tests
-a---          2020/05/14    16:34            295 pyproject.toml
-a---          2020/05/14    16:34              0 README.rst

```

### 依存関係の追加
Alibaba CloudのSDKを追加します。

``` 
PS C:\Users\user\Documents\py-sample\sample> poetry add aliyun-python-sdk-core
Using version ^2.13.16 for aliyun-python-sdk-core

Updating dependencies
Resolving dependencies...

Writing lock file


Package operations: 3 installs, 0 updates, 0 removals

  - Installing jmespath (0.10.0)
  - Installing pycryptodome (3.9.7)
  - Installing aliyun-python-sdk-core (2.13.16)

```

```
PS C:\Users\user\Documents\py-sample\sample> poetry add aliyun-python-sdk-imagesearch
Using version ^2.0.0 for aliyun-python-sdk-imagesearch

Updating dependencies
Resolving dependencies...

Writing lock file


Package operations: 1 install, 0 updates, 0 removals

  - Installing aliyun-python-sdk-imagesearch (2.0.0)

```

### 前回作成したImage Searchにアクセスする

アクセスキーとシークレットキーは前回作成したものを使用します。
また、リージョンとエンドポイントについては、以下の表から設定します。今回は日本（東京）を設定します。

| リージョン | エンドポイント |
|:-:|:-:|
| シンガポール  | imagesearch.ap-southeast-1.aliyuncs.com  |
| 中国 (香港)  | imagesearch.cn-hongkong.aliyuncs.com  |
| 日本 (東京)  | imagesearch.ap-northeast-1.aliyuncs.com  |
| オーストラリア (シドニー)  | imagesearch.ap-southeast-2.aliyuncs.com  |

``` imagesearch.py
# -*- coding: utf8 -*-

from aliyunsdkcore.client import AcsClient
import base64
import aliyunsdkimagesearch.request.v20190325.AddImageRequest as AddImageRequest
import aliyunsdkimagesearch.request.v20190325.DeleteImageRequest as DeleteImageRequest
import aliyunsdkimagesearch.request.v20190325.SearchImageRequest as SearchImageRequest

# AccessKey
ACCESS_KEY = "XXXXXXXXXXXXXXX"
SEACRET_KEY = "YYYYYYYYYYYYYY"

# AcsClient インスタンスの作成
client = AcsClient(ACCESS_KEY, SEACRET_KEY, "ap-northeast-1")
# 検索
request = SearchImageRequest.SearchImageRequest()
request.set_endpoint("imagesearch.ap-northeast-1.aliyuncs.com")
request.set_InstanceName("itemsearch")
with open('search01.jpg', 'rb') as imgfile:
    encoded_pic_content = base64.b64encode(imgfile.read())
    request.set_PicContent(encoded_pic_content)
response = client.do_action_with_exception(request)
print(response)

```

``` result.json
b'{"Msg":"success","Head":{"DocsFound":11,"DocsReturn":10,"SearchTime":100},"RequestId":"D56A620C-3EF5-461C-85FE-AFC89B6C79BB","Auctions":[{"CategoryId":9,"PicName":"12.jpg","CustomContent":"k1:v12,k2:v211,k3:v311","ProductId":"1011","SortExprValues":"3.07306838035583;217"},{"CategoryId":9,"PicName":"11.jpg","CustomContent":"k1:v11,k2:v210,k3:v310","ProductId":"1010","SortExprValues":"2.97270393371582;222"},{"CategoryId":9,"PicName":"09.jpg","CustomContent":"k1:v09,k2:v208,k3:v308","ProductId":"1008","SortExprValues":"2.87724995613098;238"},{"CategoryId":9,"PicName":"10.jpg","CustomContent":"k1:v10,k2:v209,k3:v309","ProductId":"1009","SortExprValues":"2.79507827758789;235"},{"CategoryId":9,"PicName":"02.jpg","CustomContent":"k1:v02,k2:v201,k3:v301","ProductId":"1001","SortExprValues":"2.67687916755676;251"},{"CategoryId":9,"PicName":"05.jpg","CustomContent":"k1:v05,k2:v204,k3:v304","ProductId":"1004","SortExprValues":"2.67470407485962;249"},{"CategoryId":9,"PicName":"06.jpg","CustomContent":"k1:v06,k2:v205,k3:v305","ProductId":"1005","SortExprValues":"2.66586232185364;254"},{"CategoryId":9,"PicName":"04.jpg","CustomContent":"k1:v04,k2:v203,k3:v303","ProductId":"1003","SortExprValues":"2.63756942749023;255"},{"CategoryId":9,"PicName":"01.jpg","CustomContent":"k1:v01,k2:v200,k3:v300","ProductId":"1000","SortExprValues":"2.57631182670593;270"},{"CategoryId":9,"PicName":"07.jpg","CustomContent":"k1:v07,k2:v206,k3:v306","ProductId":"1006","SortExprValues":"2.52564144134521;253"}],"PicInfo":{"CategoryId":9,"AllCategories":[{"Id":0,"Name":"Tops"},{"Id":1,"Name":"Dress"},{"Id":2,"Name":"Bottoms"},{"Id":3,"Name":"Bag"},{"Id":4,"Name":"Shoes"},{"Id":5,"Name":"Accessories"},{"Id":6,"Name":"Snack"},{"Id":7,"Name":"Makeup"},{"Id":8,"Name":"Bottle"},{"Id":9,"Name":"Furniture"},{"Id":20,"Name":"Toy"},{"Id":21,"Name":"Underwear"},{"Id":22,"Name":"Digital device"},{"Id":88888888,"Name":"Other"}],"Region":"140,474,36,578"},"Code":0,"Success":true}'

```

前回、管理画面から投げた結果と同じ結果が出力されました。Pythonでも簡単に検索する事ができました。