농구 (B 리그) 데이터를 서버리스로 얻기

옛날, 푹신 푹신한 농구 분석 에서 했던 것을, 좀 더 발전시켜 데이터를 취득해, GCP의 Storage에 보존할 수 있을 때까지를 cloud functions를 사용해 구현했습니다.

구성



이번에는 스포나비의 BOX 스코어를 1경기씩 얻어서 tsv파일로 하고 Storage에 저장합니다.
그래서 cloud functions의 python3.7에서 트리거를 HTTP로 만들었습니다.
HTTP 트리거 매개변수에 경기 날짜 또는 경기 번호를 지정하여 특정 경기 결과를 얻습니다.

폴더 구성은 다음과 같이 했습니다.
gcf_bleague_boxscore
├── main.py
└── requirements.txt

구현



파이썬의 BeautifulSoup에서 데이터를 검색하고 검색하려는 데이터를 성형합니다.
cloud functions의 실행 환경에서는/tmp를 임시 영역으로 사용할 수 있기 때문에 거기를 이용하여 tsv 파일을 작성하고 있습니다.

main.py
import pandas as pd
from bs4 import BeautifulSoup
import urllib.request
import re
from google.cloud import storage

def bleaue_boxscore(request):
    request_json = request.get_json()

    # 基本情報の設定
    if request_json and 'target_date' in request_json:
        TARGET_DATE = request_json['target_date']
    else:
        TARGET_DATE = '19900101'
    if request_json and 'target_game' in request_json:
        TARGET_GAME = request_json['target_game']
    else:
        TARGET_GAME = '3269'
    if request_json and 'div' in request_json:
        DIV = request_json['div']
    else:
        DIV = 'b1'
    URL_TOP = 'https://sportsnavi.ht.kyodo-d.jp/basketball/stats/'+DIV+'/score/'+TARGET_GAME+'/'
    URL_BOXSCORE =  URL_TOP+'box/'
    OUTPUT_FILENAME = 'boxscore_P'+TARGET_DATE+TARGET_GAME+'.tsv'

    # チーム名の取得
    html = urllib.request.urlopen(URL_TOP)
    top = BeautifulSoup(html, 'html5lib')
    team = top.find_all('div', class_='name')
    home_name = team[0].text.translate(str.maketrans({' ': '', '\n': ''}))
    away_name = team[1].text.translate(str.maketrans({' ': '', '\n': ''}))

    # 試合情報の取得(日付,tipoff,試合会場,節,カテゴリ) 
    loc = top.find('div', class_='note').string
    section = top.section.h1.string
    game_date = re.match(r'[0-9]{4}年[0-9]{1,2}月[0-9]{1,2}日' , loc).group()
    tipoff_time = re.search(r'[0-9]{1,2}:[0-9]{1,2}' , loc).group()
    arena = re.sub(r'.*試合会場:', '' , loc)
    sec = re.search(r'第[0-9]{1,2}節', section).group().translate(str.maketrans({'第': '', '節': ''}))
    div = re.match(r'B[0-9]{1}', section).group()

    # それぞれのボックススコアを取得
    tables_home = pd.read_html(URL_BOXSCORE + 'h/', flavor='bs4')
    tables_away = pd.read_html(URL_BOXSCORE + 'a/', flavor='bs4')

    # ボックススコアに情報を追加
    boxscore_home = tables_home[1].dropna(subset=['#']).assign(
                                        team=home_name,
                                        game_date=game_date,
                                        tipoff_time=tipoff_time,
                                        arena=arena,
                                        sec=sec,
                                        div=div)
    boxscore_away = tables_away[1].dropna(subset=['#']).assign(
                                        team=away_name,
                                        game_date=game_date,
                                        tipoff_time=tipoff_time,
                                        arena=arena,
                                        sec=sec,
                                        div=div)
    boxscore = pd.concat([boxscore_home, boxscore_away],ignore_index=True)

    boxscore.to_csv('/tmp/'+OUTPUT_FILENAME, sep='\t' ,header=False, index=False)

    # storageにファイルをアップロード
    storage_client = storage.Client()
    bucket = storage_client.get_bucket('ストレージのバケット名')
    blob = bucket.blob('data/'+OUTPUT_FILENAME)
    blob.upload_from_filename('/tmp/'+OUTPUT_FILENAME)

    return f'functions finished.'+OUTPUT_FILENAME

requirements.txt
google-cloud-storage
bs4
html5lib
pandas

다음 명령으로 배포합니다.
gcloud beta functions deploy bleaue_boxscore --trigger-http --runtime=python37

사용해 본 느낌



배포가 완료되면 API URL이 지불되므로 요청 매개변수에 경기 정보를 입력하고 POST하여 데이터를 검색할 수 있습니다.
curl -X POST https://[リージョン]ー[プロジェクト名]cloudfunctions.net/bleaue_boxscore -H "Content-Type:application/json" --data '{"target_date":"20190421","target_game":"3525","div":"b1"}'

좋은 웹페이지 즐겨찾기