APIを利用して場所名の緯度経度から近隣の店舗を表示する構築

#　はじめに
新年あけましておめでとうございます。
コロナが落ち着き始めた年末、お店を予約したりするという機会があったもので『場所を送っただけで近隣店舗の情報が表示することが出来たら楽になるなぁ』というキッカケでAPIを２つ掛け合わせた構築を考えてみました。

#　参考資料
参考リンクには今回作成した大元になる方のハンズオンです。HotpepperAPIを利用する部分についてご参考にさせていただきました、なによりお手本があると大変助かり理解も捗りました。

__[Hotpepper API を使って指定した地点の近くの飲食店を検索する](https://coffee-nominagara.com/hotpepper-api)__
__[ホットペッパーのAPIを使ってレストランのデータを取得する](https://zenn.dev/kohhee/articles/d4f96624b82e50)__

#　構成図
![スクリーンショット 2022-01-01 10.51.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/8f996920-7aea-eef7-d78f-8928bb479d12.png)


#　ハンズオン
## 1：コードの記述
サンプルコード（コメントアウトで各動作の内容記述あり）

```python:neighborhood_stores.py
# ライブラリのインポート
import requests
import json
import os #環境変数のため
from dotenv import load_dotenv #環境変数のため
load_dotenv()

#環境変数
yahoo_api_key  = "&appid=" + os.getenv('YAHOO')#.envに記述されている環境変数を代入する
hotpepper_api_key = "?key=" + os.getenv('HOTPEPPER')#.envに記述されている環境変数を代入する

#yahooジオコーダ変数
geo_api_url = "https://map.yahooapis.jp/geocode/V1/geoCoder?"
y_parm1 = "&output=json" #APIのレスポンスをjson形式に指示す
y_parm2 = "&query=" #調べたい場所の引数のプレフィックス

#hotpepper変数
shop_api_url = 'http://webservice.recruit.co.jp/hotpepper/gourmet/v1/'
h_parm3 = "&range=2" #緯度経度から500m以内の範囲
h_parm4 = "&order=4" #おすすめ順
h_parm5 = "&count=5" #最大データ取得件数（上位5店舗）
h_parm6 = "&format=json"#APIのレスポンスをjson形式に指示す

#緯度経度を抽出する
def Find_latitude_and_longitude(area):
  # 変数
  geo = geo_api_url + yahoo_api_key + y_parm1 + y_parm2 + area # Yahoo!ジオコーダによる取得したい場所の情報をURLにする
  geo_info = requests.get(geo) #リクエストする
  geo_obj = json.loads(geo_info.text)#リクエストしたjsonの内容を解析する
  geo_parm = geo_obj["Feature"][0]["Geometry"]["Coordinates"] # オブジェクトから座標情報を取得する
  geo_parm_list = geo_parm.split(",")# 取得した座標をカンマごとにリストで分ける
  latitude = geo_parm_list[1] #緯度
  longitude = geo_parm_list[0] #経度
  return(latitude,longitude) #緯度・経度を返す  

#緯度経度から近くの店舗を抽出する
def Look_up_nearby_stores(latitude,longitude):
  # 変数
  h_parm1 = "&lat=" + latitude
  h_parm2 = "&lng=" + longitude
  hotpepper = shop_api_url + hotpepper_api_key + h_parm1 + h_parm2 + h_parm3 + h_parm4 + h_parm5 + h_parm6

  hotpepper_info = requests.get(hotpepper)#リクエストする
  hotpepper_obj = json.loads(hotpepper_info.text)#リクエストしたjsonの内容を解析する
  hotpepper_parm = hotpepper_obj["results"]["shop"]# jsonからショップ情報を取得する
  return([d.get("name") for d in hotpepper_parm])

if __name__ == "__main__":
  print("周辺情報500mの情報を知りたい町名を記入ください")
  #area = input()
  area = "埼玉県川口市"
  print(area + "から500m圏内の店舗を出力します")
  latitude,longitude = Find_latitude_and_longitude(area)
  hotpepper_parm_list = Look_up_nearby_stores(latitude,longitude)

#抽出されたリストを1つずつ表示する
  for n,i in enumerate(hotpepper_parm_list,1): #enumerateでリストの順番も表示させる
    print(str(n) + ":" + str(i))
```
## 2:部分的な説明
### 2.1 今回利用するライブラリをインストールする

```python:neighborhood_stores.py
# ライブラリのインポート
import requests
import json
import os #環境変数のため
from dotenv import load_dotenv #環境変数のため
load_dotenv()
```
.envファイルを元に、load_dotenvでファイルの中身を読み取り環境変数を代入する

### 2.2 .envの環境変数を代入する
```python:neighborhood_stores.py
#環境変数
yahoo_api_key  = "&appid=" + os.getenv('YAHOO')#.envに記述されている環境変数を代入する
hotpepper_api_key = "?key=" + os.getenv('HOTPEPPER')#.envに記述されている環境変数を代入する
```

```terminal:ディレクトリの構成
.
├── .env
└── hotpepper
    └── neighborhood_stores.py
```

### 2.3 関数で利用するの変数を代入する

```python:neighborhood_stores.py
#yahooジオコーダ変数
geo_api_url = "https://map.yahooapis.jp/geocode/V1/geoCoder?"
y_parm1 = "&output=json" #APIのレスポンスをjson形式に指示す
y_parm2 = "&query=" #調べたい場所の引数のプレフィックス

#hotpepper変数
shop_api_url = 'http://webservice.recruit.co.jp/hotpepper/gourmet/v1/'
h_parm3 = "&range=2" #緯度経度から500m以内の範囲
h_parm4 = "&order=4" #おすすめ順
h_parm5 = "&count=5" #最大データ取得件数（上位5店舗）
h_parm6 = "&format=json"#APIのレスポンスをjson形式に指示す
```
__[Yahoo!ジオコーダAPI](https://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/geocoder.html)__についての詳細
__[グルメサーチAPI](https://webservice.recruit.co.jp/doc/hotpepper/reference.html)__についての詳細

### 2.4 Find_latitude_and_longitude()関数

```python:neighborhood_stores.py
#緯度経度を抽出する
def Find_latitude_and_longitude(area):
  # 変数
  geo = geo_api_url + yahoo_api_key + y_parm1 + y_parm2 + area # Yahoo!ジオコーダによる取得したい場所の情報をURLにする
```
引数`area`を受け取り`geo`に代入する

```python:neighborhood_stores.py
  geo_info = requests.get(geo) #リクエストする
  geo_obj = json.loads(geo_info.text)#リクエストしたjsonの内容を解析する
  geo_parm = geo_obj["Feature"][0]["Geometry"]["Coordinates"] # オブジェクトから座標情報を取得する
```
__[Yahoo!ジオコーダAPI レスポンスフィールド](https://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/geocoder.html#response_field)__についての詳細(下記画面は一部抜粋)
![スクリーンショット 2022-01-01 12.38.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/58e21954-18f3-0e34-07f1-f2e1a64b8480.png)

__ブラウザでURLを押下した際の画面抜粋__
![スクリーンショット 2022-01-01 13.22.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/77ce92b8-72e9-bfde-58fb-555ef57bdc27.png)


```python:neighborhood_stores.py
  geo_parm_list = geo_parm.split(",")# 取得した座標をカンマごとにリストで分ける
  latitude = geo_parm_list[1] #緯度
  longitude = geo_parm_list[0] #経度
  return(latitude,longitude) #緯度・経度を返す
```
座標情報では経度・緯度の順番で取得できるので、それぞれを緯度・経度の変数に代入して`return`する

### 2.5 Look_up_nearby_stores()関数

```python:neighborhood_stores.py
#緯度経度から近くの店舗を抽出する
def Look_up_nearby_stores(latitude,longitude):
  # 変数
  h_parm1 = "&lat=" + latitude
  h_parm2 = "&lng=" + longitude
  hotpepper = shop_api_url + hotpepper_api_key + h_parm1 + h_parm2 + h_parm3 + h_parm4 + h_parm5 + h_parm6
```
![スクリーンショット 2022-01-01 13.16.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/b0177ddc-be1f-fc46-2e2f-3006f1482da7.png)
引数`latitude,longitude`から緯度(`&lat=`)経度(`&lng=`)に変数を代入する

```python:neighborhood_stores.py
  hotpepper_info = requests.get(hotpepper)#リクエストする
  hotpepper_obj = json.loads(hotpepper_info.text)#リクエストしたjsonの内容を解析する
  hotpepper_parm = hotpepper_obj["results"]["shop"]# jsonからショップ情報を取得する
  return([d.get("name") for d in hotpepper_parm])
```
__[ホットペッパーAPI レスポンスフィールド](https://webservice.recruit.co.jp/doc/hotpepper/reference.html)__についての詳細(下記画面は一部抜粋)
![スクリーンショット 2022-01-01 13.30.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/5bc40a9a-7cd0-ad87-2eda-896440985b90.png)

__ブラウザでURLを押下した際の画面抜粋__
![スクリーンショット 2022-01-01 13.41.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694365/3b171d03-21c8-63cb-a457-d20cc4a7a945.png)
今回は掲載店名（『2.3 関数で利用するの変数を代入する』）で5つとしているので、5店舗をリストにして`return`する

### 2.6 モジュールを直接実行したときだけ実行するという動作の指定

```python:neighborhood_stores.py
if __name__ == "__main__":
  print("周辺情報500mの情報を知りたい町名を記入ください")
  #area = input()
  area = "埼玉県川口市"
  print(area + "から500m圏内の店舗を出力します")
  latitude,longitude = Find_latitude_and_longitude(area)
  hotpepper_parm_list = Look_up_nearby_stores(latitude,longitude)
```
`area=input()`のコメントアウトを消して、`area = "埼玉県川口市"`をコメントアウトした場合にターミナルで取得したい場所を聞かれる

```python:neighborhood_stores.py
#抽出されたリストを1つずつ表示する
  for n,i in enumerate(hotpepper_parm_list,1): #enumerateでリストの順番も表示させる
    print(str(n) + ":" + str(i))
```
`enumerate`を利用して出力順に番号を表示し、取得したリスト5つ（2.3 関数で利用するの変数を代入する `h_parm4 = "&order=4" #おすすめ順`）が表示される
` for n,i in enumerate(hotpepper_parm_list,1)`の`1`は、出力順の際に1から数え始めるということを意味してる

## 3：挙動の確認

```terminal:ターミナルで押下する
tetutetu214@mbp 0_Qiita_hanson % python　neighborhood_stores.py
周辺情報500mの情報を知りたい町名を記入ください
埼玉県川口市から500m圏内の店舗を出力します
1:三代目鳥メロ 川口東口店
2:居酒屋 福招門 川口店
3:炭火串焼 ひら井 川口店
4:タンブレロ Tamburello 4909 川口店
5:牛繁 ぎゅうしげ 川口店
```

#　さいごに
APIとして処理する方法は変わりませんが二つの異なるサービス（Yahoo,RECRUIT）を利用しながらの構築は、つくれるサービスの幅を広くしすることが出来るなと思いながら構築をしていました。調べたい場所を記入するだけではなく、GPSで今いる場所を取得したりなど、まだまだ利用しやすいとは思いませんが2022年まず一つめの記事とします。
今年もより手を動かしながらコード理解を深めていきたいと思います。