Python3 でサードパーティ製のパッケージを使うことにより更に簡単に様々な動作が実現されます。
今回は、その中から HTTP通信を行うことができるrequestsパッケージを使ってみます。
かなり簡単でびっくりしました。
次回は入力した単語をWikipediaで調べてくれる wikipediaパッケージを使ってみたを書きます。
事前準備
様々なパッケージをインストールできるので、バージョン管理などがかなり面倒になります。
そこで、Pythonの仮想環境 venv を使うことで異なるPython環境を構築しインストール、検証を行っていくという手段をとります。
仮想環境とは
通常仮想環境というと、同じコンピューターの中に別のコンピュータを仮想的に作ってある環境のことを想像すると思います。その中にはハイパーバイザー型やコンテナ型という概念が出てくるのですがこの venv での仮想環境はそれとは異なります。
venvは、異なるバージョン、異なる種類のパッケージをインストールしたPython環境を独立して作るためのものです。
プロジェクトごとにこの仮想環境を分けることでインストールしたパッケージ管理をしやすくし、開発がスムーズに進むことができるというわけです。
venv を用いた仮想環境作成
コマンドを入力します。
python3 -m venv 任意の環境名
これだけで環境が作成できます。作成後にコマンドを入力した際のカレントディレクトリを見てみると、入力した環境名のディレクトリが作成されているはずです。
仮想環境を有効化するには、macの場合以下のようになります。
source 作成した環境名(ディレクトリ名)/bin/activate
例
source env/bin/activate
Windowsの場合は、少し異なり以下のようになります。
作成した環境名(ディレクトリ名)\Scripts\activate.bat
例
env\Scripts\activate.bat
すると、ターミナル(コマンドプロンプト)の横に(作成した環境名)が表示されるようになります。
この状態で試したいパッケージをインストールしていくことによりプロジェクトごとに管理が可能になるのです。
仮想環境から抜けたいときは、以下のコマンドを入力します。
deactive
pip を知る
pipは、Pythonパッケージのインストールなどを行うものです。Python 3.4以降には、標準で付属しています。
コマンドは、pip ではなく、 pip3 で行います。(紛らわしい!笑)
覚えておきたい pip コマンド
使うコマンドは以下の3つです。
pip3 install {パッケージ名}
パッケージ名を指定してインストールするコマンドです。
pip3 uninstall {パッケージ名}
パッケージ名を指定してアンインストールするコマンドです。
pip3 list
現在の環境にインストールされているパッケージを一覧で確認できるコマンドです。
requests パッケージ
requests ライブラリとは
request パッケージは、PythonにHTTP通信を行うrequest ライブラリを提供します。Pythonには標準でurlib.requestライブラリがあるのですがそれよりも使いやすく有益なライブラリだそうです。
requests パッケージをインストールする
まずは仮想環境に移動します。
source 作成した環境名(ディレクトリ名)/bin/activate
その上で、インストールコマンドを入力します。
pip3 install requests
念の為確認してみます。
pip3 list
と入力し、一覧の中に requestsがあればOKです。
requests を使って、livedoorのお天気サービスのWeb APIを使ってみる
Web API
Web APIとは、プログラム同士がやり取りするためのインターフェース(Application Programming Interface)です。
といっても抽象的なので、ちまたにある様々なサービスでこのWeb APIを公開している場合に、そのサービスの情報を取得できたりする便利機能です。
livedoorのお天気サービスを見てみる
URLはこちらです。
見ると、どうやって情報を取得してくるのか、どういった情報が取れるのかが書いてあります。
リクエストパラメータ
http://weather.livedoor.com/weather_hacks/webservice
JSONデータをリクエストする際のベースとなるURLは以下になります。
http://weather.livedoor.com/forecast/webservice/json/v1
このURLに下の表のパラメータを加え、実際にリクエストします。
全国の地点が数字で都市コードとして分類されているようなのでこの都市コードを設定することで取得ができそうです。
そして、結果はJSON(JavaScript Object Notation)形式で返されるとのことなので、取得したJSONデータを整形して上げる必要がありそうです。
JSONはこんな形式のデータ
{
'city': '東京',
'weather': '雨',
'date': '2020-03-21',
}
天気のコマンドを関数化
今回は、weather.pyのようなファイルを用意しそこに天気コマンドのロジックを作っていきます。(コメント多めなのは自分の理解のためでもありますのでご了承ください。。。)
def weather_command():
# 基本のAPI URLを base_urlに代入
base_url = 'http://weather.livedoor.com/forecast/webservice/json/v1'
# 東京のcity code を city_codeに代入
city_code = '130010'
# URLを作成
url = '{}?city={}'.format(base_url, city_code)
# データの取得
r = requests.get(url)
# jsonデータを整形
weather_data = r.json()
# 都市名の取得
city = weather_data['location']['city']
# 日付を取得
label = weather_data['forecasts'][0]['dateLabel']
# 天気を取得
telop = weather_data['forecasts'][0]['telop']
response = '{}ノ{}ノ天気ハ、【{}】デス。'.format(city, label, telop)
return response
関数を作成したら、ボットにインポートして利用できるようにしていきます。ボットのファイル名は、pybot.py としています。
上の方に関数の読み込み from weather import weather_command を指定します。
そしてボットで使えるように
if '天気' in command:
response = weather_command()
を追加し、「天気」という入力があったら、東京の天気を答えてくれるようにします。
# eto.pyで定義した、eto_command関数を利用できるようにする。
from eto import eto_command
# random.pyで定義した、choice_command関数とdice_command関数を利用できるようにする。
from random_random import choice_command, dice_command
# datetime.pyで定義した、today_command関数とnow_command関数とweekday_command関数を利用できるようにする。
from date_time import today_command, now_command, weekday_command
# weather.pyで定義した、weather_command関数を利用できるようにする。
from weather import weather_command
def heisei_command(command):
# 文字列を分割して、それぞれ heisei, year_str に代入
heisei, year_str = command.split()
# try ~ except : year_str に数字の文字列以外が入力された際の例外処理
#try:
# try ~ except を使わずに例外処理を作る。 isdigit()メソッド
if year_str.isdigit():
# int型に変換した year_strを year に代入
year = int(year_str)
if year >= 1989 and year < 2020:
heisei_year = year - 1988
response = '西暦{}年ハ、平成{}年デス'.format(year, heisei_year)
else:
response = '西暦{}年ハ、平成デハアリマセン...'.format(year)
# 例外として、以下をレスポンスさせる。
#except ValueError:
# try ~ except ではなく、elseで例外処理
else:
response = '数値ヲ指定シテクダサイ'
return response
def len_command(command):
# 文字列を分割して、それぞれ heisei, year_str に代入
cmd, text = command.split()
# int型に変換した year_strを year に代入
length = len(text)
response = '文字列ノ長サハ {} 文字デス'.format(length)
return response
# 別ファイル hello.txt をUTF-8でファイルオープン
command_file = open('hello.txt', encoding='utf-8')
# 開いたファイルを読む
raw_data = command_file.read()
# 読んだファイルを閉じる
command_file.close()
# 行ごとの文字列に分割し、linesに代入
lines = raw_data.splitlines()
# 挨拶用の空の辞書を作成
bot_dict = {}
for line in lines:
word_list = line.split(',')
key = word_list[0]
response = word_list[1]
bot_dict[key] = response
while True:
command = input('pybot> ')
response = ""
# 例外処理のため try ~ except
try:
for key in bot_dict:
if key in command:
response = bot_dict[key]
break
# もし平成が含まれていたら
if '平成' in command:
response = heisei_command(command)
# もし長さが含まれていたら
if '長さ' in command:
response = len_command(command)
# もし 干支 が含まれていたら
if '干支' in command:
response = eto_command(command)
# もし 選ぶ が含まれていたら
if '選ぶ' in command:
response = choice_command(command)
# もし さいころ が含まれていたら
if 'さいころ' in command:
response = dice_command()
# もし 今日 が含まれていたら
if '今日' in command:
response = today_command()
# もし 現在 が含まれていたら
if '現在' in command:
response = now_command()
# もし 曜日 が含まれていたら
if '曜日' in command:
response = weekday_command(command)
# もし、天気 が含まれていたら
if '天気' in command:
response = weather_command()
if not response:
response = 'イミワカラン'
print(response)
if 'さようなら' in command:
response = 'サヨウナラ'
break
# 上記でなければエラーを返す。
except Exception as e:
print('予期セヌ エラーガ 発生シマシタ...')
print('* 種類:', type(e))
print('* 内容:', e)
記載したら、実行してみます。
python3 pybot.py
まとめ
今回はlivedoorの天気予報でしたが、HTTP通信なのでGETだけでなくPOSTやファイルアップロード、Cookieの利用など様々なことが可能なのがこのrequestsライブラリです。
実用で使う場合にはかなりお世話になりそうです。