昔、ゆるふわに始めるバスケの分析でやったものを、もう少し発展させてデータを取得し、GCPのStorageに保存できるまでをcloud functionsを使って実装しました。
構成
今回はスポナビのBOXスコアを1試合ずつ取得して、tsvファイルにしてStorageに保存します。
そのため、cloud functionsのpython3.7でトリガーをHTTPにしました。
HTTPトリガーのパラメータに試合日や試合番号を指定することで特定の試合結果を取得します。
フォルダ構成は以下のようにしました。
gcf_bleague_boxscore
├── main.py
└── requirements.txt
実装
pythonの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"}'