上司から「飲み会のセッティングよろしく!奮発したところで!」という仕事が振られたのですが、そのセッティングや予約を後回しにしてしまい、 直前になってバタバタしてしまっています。
そして、今回の反省を踏まえ、効率よくお店候補を集める方法がないか考えています。
飲み会の店決めめんどくさくて放置してたらちょっと大変になったから、APIたたいたらレコメンド出てきてチェックつけて合い見積もり取ってくれるサービスがほしい
— 黒めだか (@takeshi0406) 2016年5月14日
そうだ!HotPepperをクローリングして、GoogleCloudVisionAPIで肉画像を判定してあげればいいんだ!
— 黒めだか (@takeshi0406) 2016年5月14日
この第一歩として、とりあえずうちの部署には肉好きな方が多いので、
というロジックで、楽にお店の候補を収集するツールが作れないかと考え、 Google Cloud Vision APIを試してみることにしました。
Pythonのサンプルコード
私はPython3系が好きなので、例によってPython3.5で書いています。
import requests import base64 import json GOOGLE_CLOUD_VISION_API_URL = 'https://vision.googleapis.com/v1/images:annotate?key=' API_KEY = 'YOUR API KEY' # GCPで登録したAPIのキーに書き換えてください def request_cloud_vison_api(image_base64): api_url = GOOGLE_CLOUD_VISION_API_URL + API_KEY req_body = json.dumps({ 'requests': [{ 'image': { 'content': image_base64.decode('utf-8') # bytes型のままではjsonに変換できないのでstring型に変換する }, 'features': [{ 'type': 'LABEL_DETECTION', 'maxResults': 10, }] }] }) res = requests.post(api_url, data=req_body) return res.json() def img_to_base64(filepath): with open(filepath, 'rb') as img: img_byte = img.read() return base64.encodebytes(img_byte) # あらかじめ./niku.jpgに肉画像を保存しておく img_base64 = img_to_base64('./niku.jpg') result = request_cloud_vison_api(img_base64) print(result)
APIを叩いた結果
こちらのお店の
お肉4種の水晶板焼を楽しめる♪ 【熟成肉コース】 時間無制限飲み放題付!全8品 8000円⇒7500円 | ビストロK(焼肉・韓国料理) | ホットペッパーグルメ
こちらの画像を判定したら、このような結果になりました。
{'responses': [{'labelAnnotations': [{'description': 'meal', 'mid': '/m/0krfg', 'score': 0.95814741}, {'description': 'dish', 'mid': '/m/02q08p0', 'score': 0.94838434}, {'description': 'food', 'mid': '/m/02wbm', 'score': 0.93717068}, {'description': 'buffet', 'mid': '/m/03vc65', 'score': 0.88017672}, {'description': 'asian food', 'mid': '/m/01r1z5', 'score': 0.81001866}, {'description': 'yakiniku', 'mid': '/m/06sr5g', 'score': 0.76712012}, {'description': 'chinese food', 'mid': '/m/01xw9', 'score': 0.75738144}, {'description': 'lunch', 'mid': '/m/0jfd5', 'score': 0.69245374}, {'description': 'restaurant', 'mid': '/m/06l8d', 'score': 0.67063224}, {'description': 'hot pot', 'mid': '/m/04y0_x', 'score': 0.66542172}]}]}
'yakiniku'というタグが存在していますね
次に、こちらのお店の
【月・火・土・日・祝限定】時間無制限飲み放題!!和牛サーロイン付き♪≪極選コース≫ 7490円 | 炉端焼 うだつ 新橋店(居酒屋) | ホットペッパーグルメ
この画像
{'responses': [{'labelAnnotations': [{'description': 'food', 'mid': '/m/02wbm', 'score': 0.95109516}, {'description': 'dish', 'mid': '/m/02q08p0', 'score': 0.94914007}, {'description': 'meal', 'mid': '/m/0krfg', 'score': 0.8909772}, {'description': 'buffet', 'mid': '/m/03vc65', 'score': 0.8491028}, {'description': 'asian food', 'mid': '/m/01r1z5', 'score': 0.81432122}, {'description': 'cuisine', 'mid': '/m/01ykh', 'score': 0.79676396}, {'description': 'yakiniku', 'mid': '/m/06sr5g', 'score': 0.68702412}, {'description': 'restaurant', 'mid': '/m/06l8d', 'score': 0.67065251}, {'description': 'chinese food', 'mid': '/m/01xw9', 'score': 0.64552146}, {'description': 'sukiyaki', 'mid': '/m/01r2v1', 'score': 0.64170885}]}]}
yakiniku, sukiyakiなどのタグが判定されてますね。
次に、そこまで肉っぽくないお店。ふぐ鍋のお店ですね。
★飲放付★一番人気! 泳ぎとらふぐコース 【全7品】8300円(税抜)(3人前~) | とらふぐ亭 銀座店(和食) | ホットペッパーグルメ
{'responses': [{'labelAnnotations': [{'description': 'dish', 'mid': '/m/02q08p0', 'score': 0.94715738}, {'description': 'meal', 'mid': '/m/0krfg', 'score': 0.93616253}, {'description': 'food', 'mid': '/m/02wbm', 'score': 0.93414766}, {'description': 'lunch', 'mid': '/m/0jfd5', 'score': 0.69831973}, {'description': 'asian food', 'mid': '/m/01r1z5', 'score': 0.62586468}, {'description': 'document', 'mid': '/m/015bv3', 'score': 0.61074013}, {'description': 'chinese food', 'mid': '/m/01xw9', 'score': 0.58924079}, {'description': 'seafood', 'mid': '/m/06nwz', 'score': 0.54530984}, {'description': 'dinner', 'mid': '/m/0jffp', 'score': 0.54398543}, {'description': 'hors d oeuvre', 'mid': '/m/0pqdc', 'score': 0.54184365}]}]}
こちらも'seafood'という判定がされています。Cloud Vision API、かなり精度よさそうです。
思ったこと
意外に精度よくできそうだけど、クローラーを実装するのが面倒だからホットペッパーの機能で自動タグ付けとかやってほしい。
参考にしたサイト
GCPの登録
Pythonのサンプルコード(こっちでは2系だけど)
をそれぞれ参考にさせていただきました