はじめに
前回の プログラミング初心者が Python で Slack bot 作成 [ 準備編 ]
の続きとなります。
開発環境
環境
- Python
- Docker
- Make
ツール
- Atom Editor
- iTerm 2
実践
まずは 開発環境 をクローンします。
続いてクローンしたリポジトリの src ディレクトリに weather.py
( ファイル名はご自由に ) を新規作成します。
今回使うライブラリは標準のものだけです ( Lambda では基本的に標準のもの以外使えません ) 。
import json # 追記
import urllib # 追記
import json
これを使うことで Python で JSON を扱うことができます。
import urllib
これは Python で HTTP リクエストを出すために必要なものです ( 今回は GET リクエストと POST リクエストを使います ) 。
まずは Yahoo デベロッパーネットワークで作成したリクエスト URL を変数 REQUEST_URL
に入れます。
import json
import urllib
REQUEST_URL = '作成したリクエスト URL' # 追記
次に Slack で取得した Web hook URL を変数 WEB_HOOK_URL
に入れます。
import json
import urllib
REQUEST_URL = '作成したリクエスト URL'
WEB_HOOK_URL = '取得した Web hook URL' # 追記
では実際に Yahoo 気象情報 API から情報を取得してみましょう!
import json
import urllib
REQUEST_URL = '作成したリクエスト URL'
WEB_HOOK_URL = '取得した Web hook URL'
reqg = urllib.request.Request(REQUEST_URL) # 追記
with urllib.request.urlopen(reqg) as res: # 追記
response = res.read() # 追記
1 行目は REQUEST_URL
へリクエスト ( GET ) し、結果を変数 reqg
に入れています。
噛み砕いて説明すると、
使うもの 使う機能 オブジェクト どこの
urllib .request .Request (REQUEST_URL)
こうなります。
2 行目は 1 行目で取得したものを開いて変数 res
の中に入れています。
3 行目は変数 response
の中に 2 行目で展開した変数 res
を読み込んだものを入れています。
これで変数 response
にリクエストのレスポンスが入りました。
では response
の中身を見てみましょう。
import json
import urllib
REQUEST_URL = '作成したリクエスト URL'
WEB_HOOK_URL = '取得した Web hook URL'
reqg = urllib.request.Request(REQUEST_URL)
with urllib.request.urlopen(reqg) as res:
response = res.read()
print(response) # 追記
実行してみましょう。
$ python weather.py
すると、
{
"ResultInfo": {
"Count": 1,
"Total": 1,
"Start": 1,
"Status": 200,
"Latency": 0.003538,
"Description": "",
"Copyright": "(C) Yahoo Japan Corporation."
},
"Feature": [
{
"Id": "201903252255_139.707831_35.774614",
"Name":"\xe5\x9c\xb0\xe7\x82\xb9(139.707831,35.774614)\xe3\x81\xae2019\xe5\xb9\xb403\xe6\x9c\x8826\xe6\x97\xa5 14\xe6\x99\x8220\xe5\x88\x86\xe3\x81\x8b\xe3\x82\x8960\xe5\x88\x86\xe9\x96\x93\xe3\x81\xae\xe5\xa4\xa9\xe6\xb0\x97\xe6\x83\x85\xe5\xa0\xb1",
"Geometry": {
"Type": "point",
"Coordinates": "139.707831,35.774614"
},
"Property": {
"WeatherAreaCode": 4410,
"WeatherList": {
"Weather": [
{
"Type": "observation",
"Date": "201903252255",
"Rainfall": 0
},
{
"Type": "forecast",
"Date": "201903252305",
"Rainfall": 0
},
{
"Type": "forecast",
"Date": "201903252315",
"Rainfall": 0
},
{
"Type": "forecast",
"Date": "201903252325",
"Rainfall": 0
},
{
"Type": "forecast",
"Date": "201903252335",
"Rainfall": 0
},
{
"Type": "forecast",
"Date": "201903252345",
"Rainfall": 0
},
{
"Type": "forecast",
"Date": "201903252355",
"Rainfall": 0
}
]
}
}
}
]
}
name の部分が読めませんね ( 見やすくするため整形しています )。
原因はこれが HTTPResponse オブジェクト だからです。
なので文字列に変換する必要があります。
import json
import urllib
REQUEST_URL = '作成したリクエスト URL'
WEB_HOOK_URL = '取得した Web hook URL'
reqg = urllib.request.Request(REQUEST_URL)
with urllib.request.urlopen(reqg) as res:
response = res.read()
response = response.decode() # 追記
print(response)
もう1度確認してみましょう。
$ python weather.py
すると
{
"ResultInfo": {
"Count": 1,
"Total": 1,
"Start": 1,
"Status": 200,
"Latency": 0.003538,
"Description": "",
"Copyright": "(C) Yahoo Japan Corporation."
},
"Feature": [
{
"Id": "201903252255_139.707831_35.774614",
"Name": "地点(139.707831,35.774614)の2019年03月25日 22時55分から60分間の天気情報",
"Geometry": {
"Type": "point",
"Coordinates": "139.707831,35.774614"
},
"Property": {
"WeatherAreaCode": 4410,
"WeatherList": {
"Weather": [
{
"Type": "observation",
"Date": "201903252255",
"Rainfall": 0
},
{
"Type": "forecast",
"Date": "201903252305",
"Rainfall": 0
},
{
"Type": "forecast",
"Date": "201903252315",
"Rainfall": 0
},
{
"Type": "forecast",
"Date": "201903252325",
"Rainfall": 0
},
{
"Type": "forecast",
"Date": "201903252335",
"Rainfall": 0
},
{
"Type": "forecast",
"Date": "201903252345",
"Rainfall": 0
},
{
"Type": "forecast",
"Date": "201903252355",
"Rainfall": 0
}
]
}
}
}
]
}
これで読めるようになりました。
確認が終わったのでptint(response)
は削除しましょう。
続いて変数 response
の中身を JSON に変換しましょう。
import json
import urllib
REQUEST_URL = '作成したリクエスト URL'
WEB_HOOK_URL = '取得した Web hook URL'
reqg = urllib.request.Request(REQUEST_URL)
with urllib.request.urlopen(reqg) as res:
response = res.read()
response = response.decode()
d = json.loads(response) # 追記
変数 response
が JSON に変換されたものが変数 d
に 入りました。
これを噛み砕いて説明すると、
変数 代入 json として 読み込む 何を
d = json .loads (response)
となります。
この JSON の中にはたくさんのデータが入っていますが、今回必要なのは降水強度のデータのみです。
では降水強度のみ抜き出してみましょう。
import json
import urllib
REQUEST_URL = '作成したリクエスト URL'
WEB_HOOK_URL = '取得した Web hook URL'
reqg = urllib.request.Request(REQUEST_URL)
with urllib.request.urlopen(reqg) as res:
response = res.read()
response = response.decode()
d = json.loads(response)
rainfall = d['Feature'][0]['Property']['WeatherList']['Weather'][0]['Rainfall'] # 追記
これは変数 d
の中身 ( JSON ) の Feature の 0 番目 ( dict ( 辞書 )では 0, 1, 2, 3, ... と数えます ) の Property の WeatherList の Weather の 0 番目の Rainfall の値を変数 rainfall
に代入する、という意味になります。
実際に確認してみましょう。
import json
import urllib
REQUEST_URL = '作成したリクエスト URL'
WEB_HOOK_URL = '取得した Web hook URL'
reqg = urllib.request.Request(REQUEST_URL)
with urllib.request.urlopen(reqg) as res:
response = res.read()
response = response.decode()
d = json.loads(response)
rainfall = d['Feature'][0]['Property']['WeatherList']['Weather'][0]['Rainfall']
print(rainfall) # 追記
$ python weather.py
すると、
0.0
これで無事、現在の降水強度のみを取得することができました!
確認が終わったのでprint(rainfall)
は削除してください。
では次に Slack に通知する文を書きましょう。
import json
import urllib
REQUEST_URL = '作成したリクエスト URL'
WEB_HOOK_URL = '取得した Web hook URL'
reqg = urllib.request.Request(REQUEST_URL)
with urllib.request.urlopen(reqg) as res:
response = res.read()
response = response.decode()
d = json.loads(response)
rainfall = d['Feature'][0]['Property']['WeatherList']['Weather'][0]['Rainfall']
payload_d = {
'text': '現在の赤羽駅の降水強度は {} mm/h です。'.format(rainfall)
} # 追記
今回は { } で括ったものを代入しています。
これは、変数 payload_d
に dict として代入する、という意味です。
中身は text をキーに '現在の赤羽駅の降水強度は {} mm/h です。' を値として、{} 内に、変数 rainfall の中身を表示、という意味になります。
説明ではわかりにくいですね...。
では実際に payload の中身を確認してみましょう。
import json
import urllib
REQUEST_URL = '作成したリクエスト URL'
WEB_HOOK_URL = '取得した Web hook URL'
reqg = urllib.request.Request(REQUEST_URL)
with urllib.request.urlopen(reqg) as res:
response = res.read()
response = response.decode()
d = json.loads(response)
rainfall = d['Feature'][0]['Property']['WeatherList']['Weather'][0]['Rainfall']
payload_d = {
'text': '現在の赤羽駅の降水強度は {} mm/h です。'.format(rainfall)
}
print(payload_d) # 追記
$ python weather.py
{'text': '現在の赤羽駅の降水強度は 0.0 mm/h です。'}
このように {} 内に変数 rainfall
の中身が代入されます。
確認が終わったのでprint(payload_d)
を削除してください。
ではこれを JSON に変換しましょう。
import json
import urllib
REQUEST_URL = '作成したリクエスト URL'
WEB_HOOK_URL = '取得した Web hook URL'
reqg = urllib.request.Request(REQUEST_URL)
with urllib.request.urlopen(reqg) as res:
response = res.read()
response = response.decode()
d = json.loads(response)
rainfall = d['Feature'][0]['Property']['WeatherList']['Weather'][0]['Rainfall']
payload_d = {
'text': '現在の赤羽駅の降水強度は {} mm/h です。'.format(rainfall)
}
data = json.dumps(payload_d).encode('utf-8') # 追記
これを細かく説明するとこうなります。
変数 代入 JSON として 変換 何を 文字コード
data = json .dumps (payload_d) .encode('utf-8')
次にこのデータを Slack に届ける準備をしましょう。
import json
import urllib
REQUEST_URL = '作成したリクエスト URL'
WEB_HOOK_URL = '取得した Web hook URL'
reqg = urllib.request.Request(REQUEST_URL)
with urllib.request.urlopen(reqg) as res:
response = res.read()
response = response.decode()
d = json.loads(response)
rainfall = d['Feature'][0]['Property']['WeatherList']['Weather'][0]['Rainfall']
payload_d = {
'text': '現在の赤羽駅の降水強度は {} mm/h です。'.format(rainfall)
}
data = json.dumps(payload_d).encode('utf-8')
reqp = urllib.request.Request(WEB_HOOK_URL, data, method='POST') # 追記
with urllib.request.urlopen(reqp) as res: # 追記
body = res.read().decode('utf-8') # 追記
データを届ける ( POST ) ときも urllib を使います。
データを取得したときと似ていますね。
違うところは 1 行目の method='POST'
と 2 行目の decode('utf-8')
になります。
method='POST'
は HTTP メソッドの指定になります。今回は Slack に届けてもらいたいので POST ですね。
decode('utf-8')
は文字コードの指定になります。これで Slack 側でもちゃんと読めるようになります。
以上で完成です!
試しに実行してみましょう!
$ python weather.py
このような通知が来れば成功です!
最後に
とても長くなってしまいましたが、最後までお付き合いいただきありがとうございました!
コードはこれで完成しましたが、デプロイがまだなので、次回 本番編 ということでそちらに記事を書かせていただきます。