【Python】天気予報API を用いて明日の天気を取得してみる

## はじめに
この記事では、Pythonを使用してWeb APIを取得する方法について解説します。
大体の内容は[こちらの記事](https://qiita.com/hisshi00/items/9806eceeee2237624222)にありますが、本記事では、さらに少しだけ踏み込んだ内容となっています。

## やりたいこと
[全国の地点定義表](https://weather.tsukumijima.net/primary_area.xml)のコードを入力して、[天気予報API](https://weather.tsukumijima.net/)より明日の天気予報を表示させる。


## 結果のコード
以下が今回使用するコードの全体です。
Web APIを呼び出し、その結果を取得するための基本的な流れを示しています。

```python
import requests
from datetime import datetime

def get_weather(city):
    try:
        url = f"https://weather.tsukumijima.net/api/forecast?city={city}"
        response  = requests.get(url)
        response.raise_for_status()

        data_json = response.json()
    
        date_str = data_json["forecasts"][1]["date"]
        date = datetime.strptime(date_str,"%Y-%m-%d").strftime("%Y年%m月%d日")
        title = data_json["title"]
        weather = data_json["forecasts"][1]["telop"]
        max_temp = data_json["forecasts"][1]["temperature"]["max"]["celsius"]
        min_temp = data_json["forecasts"][1]["temperature"]["min"]["celsius"]
        
        results = f"{date}の{title}は{weather}です。\n最高気温は{max_temp}度、最低気温は{min_temp}度です。"
        return results
    
    except requests.exceptions.RequestException as e:
        return f"天気情報の取得に失敗しました: {e}"
        
    except KeyError as e:
        return f"予期しないデータ形式です: {e}"

city_number = input("地点コードを入力してください: ")
result = get_weather(city_number)
print(result)
```

## コードの解説
### 1. 必要となるモジュールのインポート
```python
import requests
from datetime import datetime
```
まず、以下のモジュールをインポートします。
<dl>
  <dt>requests</dt>
  <dd>HTTPリクエストを行うための外部ライブラリ</dd>
  <dt>datetime</dt>
  <dd>日付や時間を扱うための標準ライブラリ</dd>
</dl>

### 2. APIエンドポイントの設定
```python
url = f"https://weather.tsukumijima.net/api/forecast?city={city}"
```
変数``url``に、アクセスしたいAPIのエンドポイントURLを指定します。
``{city}``には、関数``get_weather``の引数があてられます。

### 3. GETリクエストの送信
```python
response  = requests.get(url)
```
``requests``モジュールの``get``メソッドを使用して、指定したURLに対してGETリクエストを送信します。戻り値を``response``変数に格納しておきます。

### 4. ステータスコードの確認
```python
response.raise_for_status()
```
APIリクエストが成功したかどうかを確認するために、``response.status_code``を使用します。ステータスコードが200の場合、リクエストは成功しています。200番台以外だったときに、``except``部分（例外処理）を実行します。

| HTTPステータスコード | 状態               |
|:-------------------:|:-----------------:|
| 100番台             | 処理中             |
| 200番台             | 成功               |
| 300番台             | リダイレクション    |
| 400番台             | クライアントエラー  |
| 500番台             | サーバーエラー      |

### 5. JSONデータの取得
```python
data_json = response.json()
```
``response.json()``メソッドを使用して、APIから返されたJSON形式のデータをPythonの辞書型に変換します。このデータを変数``data_json``に格納します。

### 6. 必要なデータの抽出
``` python
date_str = data_json["forecasts"][1]["date"]
date = datetime.strptime(date_str,"%Y-%m-%d").strftime("%Y年%m月%d日")
title = data_json["title"]
weather = data_json["forecasts"][1]["telop"]
max_temp = data_json["forecasts"][1]["temperature"]["max"]["celsius"]
min_temp = data_json["forecasts"][1]["temperature"]["min"]["celsius"]
```
それぞれ必要とするデータを辞書型``data_json``から抽出します。
必要に応じて整形等を行います。
詳細は[天気予報APIのレスポンスフィールド](https://weather.tsukumijima.net/#:~:text=forecast%3Fcity%3D400040-,%E3%83%AC%E3%82%B9%E3%83%9D%E3%83%B3%E3%82%B9%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB%E3%83%89,-%E5%8F%96%E5%BE%97%E3%81%97%E3%81%9F%20JSON)を確認してください。

### 7. 出力文字列を作成
```python
results = f"{date}の{title}は{weather}です。\n最高気温は{max_temp}度、最低気温は{min_temp}度です。"
return results
```
### 8. エラー処理
```python
except requests.exceptions.RequestException as e:
    return f"天気情報の取得に失敗しました: {e}"
```
HTTPリクエストでエラーになった場合、このコードが実行されます。
``e``にはステータスコードが入ってきます。

```python
except KeyError as e:
    return f"予期しないデータ形式です: {e}"
```
入力された地点コードが違っていたりした場合は、このコードが実行されます。

### 9. 関数の実行 ＆ 戻り値の出力
```python
city_number = input("都市コードを入力してください: ")
result = get_weather(city_number)
print(result)
```
``input``で入力したコードを引数として、``get_weater``を実行して、返ってきた文字列を表示させます。簡略にすると、以下のようにしてもOKです。
```python
print(get_weather(input("都市コードを入力してください: ")))
```


## まとめ
今回の記事では、Pythonを使ってWeb APIを取得する基本的な方法について説明しました。requestsモジュールを利用することで、APIの利用が非常に簡単になります。

ご質問やフィードバックがあれば、コメントでお知らせください！