홈런 알림 slackbot 만들려고

소개



일본 햄의 선수가 홈런을 쳤을 때에 통지해 주는 slack bot를 만들었습니다.
단순히 홈런을 통지해주는 것만으로는 재미있지 않기 때문에, 일본 햄의 실황으로 친숙한 콘도 유우지씨의 특징적인 실황 어록으로 통지받기로 했습니다.

경기 정보는 Yahoo! JAPAN의 SportsNavi에서 스크래핑하여 취득했습니다.
처음으로 스크래핑을 했기 때문에 상당히 잡담하고 있을지도 모릅니다.

전체 개요


  • 하루 1회 cron으로 프로그램을 기동해, 일본 ​​햄의 경기 개시 시간을 취득한다.
  • Python의 sched 라이브러리를 사용하여 경기 시작 시간에 gone_bot 함수를 실행하도록 스케줄을 설정합니다.
  • 경기 시간이 되면 gone_bot 함수를 실행해, 30초에 1회 경기 정보를 취득해 일본 햄의 선수가 홈런을 쳤을 때에 통지를 한다.
  • 경기가 끝날 때 프로그램을 종료합니다.

  • 라이브러리 설치


    pip install beautifulsoup
    pip install slackweb
    

    Slack의 Webhook URL 가져오기



    프로그램에서 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초이므로 경우에 따라서는 복수회 통지하는 일이 있습니다.

    결론



    시즌의 경기가 끝나고 있으므로 초조해 만들어 투고했습니다.
    문제점에 대해서는, 갱신이 빠른 일구 속보등으로부터 스크래핑 하는 것으로 해결할 수 있을 것이므로 수정하고 싶다고 생각하고 있습니다.

    좋은 웹페이지 즐겨찾기