#はじめに
私が物心ついたころ、日本で一番強いチームは横浜ベイスターズでした。
野手では谷繁、ローズ、駒田、鈴木尚、投手では三浦、斎藤隆、佐々木など…懐かしいですね。
やっぱり子供というものは、強いチームを好きになるもので、その時私はベイスターズのファンになりました。
ご存知の通り、ベイスターズはその後衰退の一途をたどるわけですが…
最近では仕事も忙しく、ベイスターズの試合を見ることは少なくなりましたが、いまだに試合結果だけは気になってちょくちょく見てしまいます。贔屓のチームが勝つと嬉しいですもんね。
ただ逆に、結果を見てベイスターズが負けていると萎えちゃいます。仕方ないですが。
そんな中、ある日ふと思ったんです。
「ベイスターズが勝ってる時だけ教えてくれれば、気分が落ち込まずに済むな…。」
#スキル
ベイスターズ速報(非公式)
#使い方
■勝ってる時
「ベイス速報を開いて」
↓
アレクサ「現在7回表です。ベイスターズが5対2で勝っています!」
■負けてる時
「ベイス速報を開いて」
↓
アレクサ「横浜Fマリノスの結果をお調べですか?」
これなら、もしピッチャーが大炎上していても、結果を知ることなく気持ち良く一日を過ごすことができますね
#構成
Amazon Echo Dot → Alexa → AWS Lambda(Python) → Sportsnavi(プロ野球)
Alexaスキルは、AWS Lambda上でNode.jsを使って開発するのがスタンダードかと思いますが、今回はスクレイピングにBeautifulSoupを使いたかったため、Python3で実装しました。
速報情報はスポナビさんのデータを利用させていただきました。
#ソースコード
Alexaコンソールの設定は、公式のチュートリアルなどをご参考にしていただければと思います。
今回はPythonスクリプトのみ掲載します。テンプレートとして「alexa-skills-kit-color-expert-python」を利用し、こちらのコードをベースに実装しました。
この記事を書いている時に気づいたのですが、Alexa Skills Kit SDK for Pythonのベータ版が6月にリリースされていたようで、こちらを利用すればもっとコード量を削減できるかと思います。
import urllib.request
from bs4 import BeautifulSoup
import random
# --------------- Helpers that build all of the responses ----------------------
def build_speechlet_response(output):
return {
'outputSpeech': {
'type': 'PlainText',
'text': output
},
'card': {
'type': 'Simple',
'title': 'ベイスターズ速報',
'content': output
},
'reprompt': {
'outputSpeech': {
'type': 'PlainText',
'text': None
}
},
'shouldEndSession': True
}
def build_response(speechlet_response):
return {
'version': '1.0',
'sessionAttributes': {},
'response': speechlet_response
}
# --------------- Functions that control the skill's behavior ------------------
def get_baystars_result():
lose_text_list = ["今日はいい天気ですね","横浜Fマリノスの結果をお調べですか?","他人を応援するより自分が頑張ったほうが楽しいですよ","大魔神は今、馬ぬしをやっているそうです"]
html = urllib.request.urlopen('https://baseball.yahoo.co.jp/npb/schedule/').read()
soup = BeautifulSoup(html, 'html.parser')
#ベイスターズが含まれる対戦テーブルを取得
#無い場合は試合無しと判断
if soup.find(class_="yjMS",text="DeNA") == None:
speech_output = "今日は試合が無いようです"
return build_response(build_speechlet_response(speech_output))
else:
table = soup.find(class_="yjMS",text="DeNA").parent.parent
#表の上のチーム:a,下のチーム:b
team_a = table.select('.yjMS')[0].a.string
team_b = table.select('.yjMS')[1].a.string
team_a_score = table.select('.score_r')[0].string
team_b_score = table.select('.score_r')[1].string
game_status = table.select('.yjMSt')[0].string
if game_status == "結果":
lead_text = "試合終了!"
elif game_status == "中止":
lead_text = "試合は" + game_status + "になりました"
else:
lead_text = "現在" + game_status + "です"
if game_status == "試合前" or game_status == "中止":
speech_output = lead_text
elif team_a == "DeNA" and int(team_a_score) > int(team_b_score):
speech_output = lead_text + "ベイスターズは" + team_a_score + "対" + team_b_score + "で勝っています!"
elif team_b == "DeNA" and int(team_b_score) > int(team_a_score):
speech_output = lead_text + "ベイスターズは" + team_b_score + "対" + team_a_score + "で勝っています!"
else:
speech_output = random.choice(lose_text_list)
return build_response(build_speechlet_response(speech_output))
def handle_session_end_request():
speech_output = "Bye"
return build_response(build_speechlet_response(speech_output))
# --------------- Events ------------------
def on_launch(launch_request):
return get_baystars_result()
def on_intent(intent_request):
intent_name = intent_request['intent']['name']
if intent_name == "ResultIntent":
return get_baystars_result()
elif intent_name == "AMAZON.HelpIntent":
return get_baystars_result()
elif intent_name == "AMAZON.CancelIntent" or intent_name == "AMAZON.StopIntent":
return handle_session_end_request()
else:
raise ValueError("Invalid intent")
# --------------- Main handler ------------------
def lambda_handler(event, context):
if event['request']['type'] == "LaunchRequest":
return on_launch(event['request'])
elif event['request']['type'] == "IntentRequest":
return on_intent(event['request'])
elif event['request']['type'] == "SessionEndedRequest":
return on_session_ended(event['request'])
#審査について
当初「ベイスターズ速報」で審査提出したのですが、チームから承認を得ていないと審査を通さないよと言われたため、「(非公式)」を付け足しました。スキル詳細についても同様で、非公式である旨を書き足しました。
また呼び出し名については、「ベイスターズ」のワードは使用しないように指摘があったため、「ベイス速報」としました。
1.非公式である旨を明記する
2.呼び出し名に固有名詞を使わない
の2点を守れば、審査は突破できそうです
#おわりに
記事を見て少しでも面白い、参考になると思いましたら、いいねボタンを押していただけると幸いです。
また実装について、より良い方法などありましたら、コメントいただけると助かります
その他いろいろと記事を書いてますので、興味のある方はぜひ!
AIが選んだ本当に似ている有名人トップ10