좋아하는 종마의 산코마의 출주 예정을 Line에 통지한다

소개



여러분, 경마를 즐기십니까? (웃음)

이전에, 에스포아르시치라는 말의 한입 마주를 하고 있어서…
에스포아르시티는 은퇴 후 무사종마에 올라 작년부터 아이들이 레이스에 나서기 시작했다.

한입 마주로 가지고 있는 말들은 부양(?)하고 있다고 하는 일도 있어 「아이의 운동회」를 보는 느낌으로 레이스를 즐기고 있었습니다만, 그 아이들이 레이스에 나오게 되면 「손자의 운동회 '가되는 것입니다 (웃음)

그 「손자의 운동회」를 놓치지 않게, 손자들(?)의 출주가 정해지면, Line에 통지하는 환경을 구축해 보았습니다.

환경 개요


  • 공익 사단법인 일본 경종마 협회씨가 제공하고 있다 JBIS-Search 의 「종마 정보:산코마 출주 정보」를 원 데이터에 사용해 주셨습니다.
  • JBIS-Search에서 requests을 사용하여 얻은 데이터에서 BeautifulSoup을 사용하여 필요한 정보를 추출합니다.
  • 통지하고 싶은 문장에 재형성한 다음, LINE Notify
  • Heroku Scheduler를 사용해 상기 처리를 정시 실행.

  • 덧붙여 이번은 이하의 기사를 참고로 실장하고 있습니다.
    매우 도움이되었습니다. 감사합니다.

    파이썬에서 조금 자세한 날씨 정보를 LINE에 알리기 (1)
    파이썬에서 조금 자세한 날씨 정보를 LINE에 알리기 (2)
    Heroku에서 날씨 파이썬 정기 실행

    개발시 라이브러리 등의 버전


  • Python 3.7.1
  • beautifulsoup4 4.6.3
  • mojimoji 0.0.8
  • python-dotenv 0.9.1
  • requests 2.20.1

  • 구현



    산코마 출주 정보 취득, 추출



    requests를 사용해 JBIS-Search씨로부터 정보 취득, BeautifulSoup를 사용해 필요한 정보를 추출, 1마리 1마리의 정보를 namedtuple에 넣어 yield로 돌려주는 함수를 만들어 보았습니다.
    진짜는 이상계에 대한 실장해야 하지만 거기는 추종…

    jbis.py
    """JBISへのアクセス関数群."""
    import re
    import datetime
    from collections import namedtuple
    
    import requests
    from bs4 import BeautifulSoup
    
    
    def iter_sire_entries(horseid):
        """指定されたIDの種牡馬の産駒の出走予定を返す."""
        r = requests.get(f'https://www.jbis.or.jp/horse/{horseid}/sire/entry/')
        soup = BeautifulSoup(r.content, "html.parser")
        h2s = soup.find_all('h2')
        today = datetime.date.today()
    
        Entry = namedtuple(
            'Entry', ['date', 'course', 'raceno', 'racename', 'horsename'])
    
        for h2 in h2s:
            m = re.fullmatch(r"\s?([0-9]{1,2})月\s?([0-9]{1,2})日出走分", h2.string)
            month = int(m.group(1))
            day = int(m.group(2))
            date = datetime.date(
                today.year + (0 if today.month <= month else 1), month, day)
    
            for tr in h2.find_next('tbody').find_all('tr'):
                tds = tr.find_all('td')
                entry = Entry(date, tr.find('th').string,
                              tds[0].string, tds[1].text.strip(), tds[7].string)
                yield entry
    

    통지하고 싶은 문장에 성형



    위의 함수로 취득한 출주 예정을 일자로 그룹화, 그것을 한층 더 레이스 마다 그룹화해 문장을 만들고 있습니다.
    groupby를 사용하려면, 사전에 키로 소트 되고 있을 필요가 있습니다만, JBIS-Search로 취득한 시점에서 적어도 일자에서는 소트 끝난, 레이스마다는 확증은 없지만, 아무튼 소트 끝난 것일까…라는 느낌이므로 그 전제로 ...
    그리고 원래의 컨텐츠가 알파벳등이 전각이 되어 있으므로, 가나 이외는 반각으로 하기 위해, 모지모지 를 사용하게 하고 있습니다.

    espoircity_child_entry.py
    def main():
        """メイン関数."""
        p = ArgumentParser(description='エスポワールシチー産駒の出走予定をLINE Notifyに送る')
        p.add_argument('-d', '--debug', action='store_true', help='デバッグ用')
        args = p.parse_args()
    
        content = f'エスポワールシチー産駒の出走予定\n'
    
        for date, g in groupby(jbis.iter_sire_entries('0000888832'), lambda e: e.date):
            content += f'\n{date.strftime("%m/%d")}\n'
            for r, g2 in groupby(g, lambda x: (x.course, x.raceno, x.racename)):
                racename = mojimoji.zen_to_han(r[2], kana=False)
                content += f' {r[0]}{r[1]}R {racename}\n'
                for e in g2:
                    content += f'  {e.horsename}\n'
    
        if args.debug:
            print(content)
        else:
            line.notify(settings.NOTIFY_ACCESS_TOKEN, content)
    

    LINE Notify로 알림



    LINE Notify 에 대해서는 링크처를 참조.

    LINE Notify를 사용한 알림은 토큰조차 만들면 매우 간단합니다.

    line.py
    """LINEへのアクセス関数群."""
    import requests
    
    
    def notify(token, message):
        """LINE Notifyでメッセージを送る."""
        payload = {'message': message}
        headers = {'Authorization': 'Bearer ' + token}
        requests.post('https://notify-api.line.me/api/notify',
                      data=payload, headers=headers)
    

    토큰에 관해서는 소스 직접 쓰는 것은 조금…이므로, python-dotenv 를 사용해, .env 파일, 혹은 환경 변수로부터 취득하도록(듯이) 했습니다.

    settings.py
    """設定情報."""
    import os
    from os.path import dirname, join
    
    from dotenv import load_dotenv
    
    dotenv_path = join(dirname(__file__), '.env')
    load_dotenv(dotenv_path)
    
    NOTIFY_ACCESS_TOKEN = os.environ.get("NOTIFY_ACCESS_TOKEN")
    

    사용하는 쪽은 다음과 같이하면 괜찮습니다.

    espoircity_child_entry.py
    import settings
    
    (省略)
    
    line.notify(settings.NOTIFY_ACCESS_TOKEN, content)
    

    Heroku Scheduler를 사용한 정기 실행



    여기에 대해서는 완전히 Heroku에서 날씨 파이썬 정기 실행 그대로의 내용이 됩니다. 알기 쉬운 기사로 감사합니다.
    이 기사 덕분에도 있습니다만, Heroku는 이렇게 편하게 배포할 수 있는군요…라는 것이 실감…

    완성!



    실제로 12/4에 통지된 LINE 캡처입니다. 이것으로 좋아하는 종마의 산코마의 출주 예정을 놓치지 마세요!



    덧붙여 소스는 github 쪽에 있습니다.

    마지막으로



    경마도 컴퓨터를 사용하여 편안하게 즐기자! (웃음)

    좋은 웹페이지 즐겨찾기