はじめに
日本ハムの選手がホームランを打ったときに通知してくれるslack botを作りました。
単にホームランを通知してくれるだけでは面白くないので、日本ハムの実況でお馴染みの近藤祐司さんの特徴的な実況語録で通知してもらうことにしました。
試合の情報はYahoo!JAPANのSportsNaviからスクレイピングして取得しました。
初めてスクレイピングをやったので結構雑になっているかもしれないです。
全体の概要
- 1日1回cronでプログラムを起動し、日本ハムの試合開始時間を取得する。
- Pythonのschedライブラリを用いて試合開始時間にgone_bot関数を実行するようにスケジュールを設定する。
- 試合時間になったらgone_bot関数を実行し、30秒に1回試合情報を取得して日本ハムの選手がホームランを打ったときに通知をする。
- 試合が終了したときにプログラムを終了させる。
ライブラリのインストール
pip install beautifulsoup
pip install slackweb
SlackのWebhook URLを取得する
プログラムからslackに通知を送るためにWebhook URLを取得します。
取得手順は以下を参考にしました。
プログラム
get_homerun_comment
関数では5つのコメントの中から確率的に選んでもらうことにしました。
gone_bot.py
import sched
import datetime
import time
import numpy as np
from urllib.request import urlopen
from bs4 import BeautifulSoup
import slackweb
# パーサの作成
def soup_html_parser(url):
html = urlopen(url)
return BeautifulSoup(html, "html.parser")
# 日本ハムの試合開始時間取得
def get_start_time(games_today):
for game in games_today:
if len(game.find_all('a', href='/npb/teams/8/', title='日本ハム')) != 0:
return game.find('em').text
return ''
# 日本ハムの試合の状況取得
def get_game_status(games_today):
for game in games_today:
if len(game.find_all('a', href='/npb/teams/8/', title='日本ハム')) != 0:
return game.find('td', colspan='2')
return ''
# ホームランのコメントを取得
def get_homerun_comment():
comment = ['イッツゴーンヌッ!', 'イッツ!ゴーイング!ゴーイング!ゴーンヌッ!', 'イッツアウトオブヒアッ!ゴーンヌッ!', 'シーユーレイター!', 'グッバーイ!']
return np.random.choice(comment, p = [0.4, 0.15, 0.15, 0.15, 0.15])
def gone_bot():
while True:
url_date = "{0:%Y%m%d}".format(datetime.date.today())
soup = soup_html_parser('https://baseball.yahoo.co.jp/npb/schedule/?date=' + url_date)
games_today = soup.find_all('table', class_='teams')
if game_today:
status = get_game_status(game_today)
if status.get('class')[0] == 'active': # 試合中
soup_game = soup_html_parser(status.a.get('href') + 'text') # 現在の回の情報を取得
game_F = soup_game.find_all('div', class_='item F clearfix')
if len(game_F) != 0:
bat_now = game_F[0].find_all('li')[-1] # 現在のバッターの情報を取得
if bat_now.find('b', class_='red') and bat_now.b.contents[-1].find('ホームラン') != -1: # 自軍の得点(ホームラン)
# *****にincoming webhookのurlを入力
slack = slackweb.Slack('*****')
slack.notify(text = bat_now.a.text + '!' + get_homerun_comment() + '\n' + bat_now.b.contents[-1])
elif status.get('class')[0] == 'end': # 試合終了
break
time.sleep(30)
if __name__ == '__main__':
url_date = "{0:%Y%m%d}".format(datetime.date.today())
soup = soup_html_parser('https://baseball.yahoo.co.jp/npb/schedule/?date=' + url_date)
if games_today:
start_time = get_start_time(games_today)
if start_time != '':
scheduler = sched.scheduler(time.time, time.sleep)
run_at = datetime.datetime.strptime(str(datetime.date.today()) + ' ' + start_time, '%Y-%m-%d %H:%M')
run_at = int(time.mktime(run_at.utctimetuple()))
scheduler.enterabs(run_at, 1, gone_bot)
scheduler.run()
cronの設定
毎日12時にプログラムを実行するようにしました。
下記では省略していますが絶対パスで指定します。
0 12 * * * bash -l -c '/home/.../python /home/.../gone_bot.py &'
実行結果
問題点
現在はテキスト速報からスクレイピングしているので更新が遅いときは、スクレイピングのインターバルが30秒なので場合によっては複数回通知することがあります。
おわりに
シーズンの試合が終わりかけているので焦って作って投稿しました。
問題点については、更新の速い一球速報などからスクレイピングすることで解決できそうなので修正したいと考えています。