シン・アナゴのブログ

下手だけどカメラやガジェットが好きなただのおっさん。

バスケのスタッツを収集しよう!

初めましての方は初めまして、そうでない方も初めまして(強制) Basketballnaviというところでこれを作った者です。

NBAだと公式サイトがこんな素敵なものを用意してくれたりメディアなどで細かいデータまで用意してくれます。 (リンク先は全て別ウィンドウで開きます)

ですが日本のバスケリーグになると公式のものは単純なアベレージだけだったりチームのスタッツが全く充実してなかったり、1シーズンでデータを吹っ飛ばしてしまうリーグもありますので、なんとかならんものかとここ数年悩んでいました。

ネックはデータ収集そのもの

さて、スタッツのデータに関して一番ネックになるものは何でしょうか? それはなんといってもデータ収集作業です。

リーグの関係者、チームの関係者であれば(恐らく)入手可能なんでしょうが一般人の自分にとっては入手不可能な代物。となると公式からデータ収集をして自分で作らないといけないんですが1試合ごとのデータをExcelに手打ちなんて苦行でしかありません。苦行というか何かの修行です。いや、罰ゲームです。一時期頑張ってやってましたがこういうのは続かないものです。

そこで出会ったのがスクレイピングという技術。要するに公式サイトのボックススコアから数字の部分をパクるスクレイピング(削る)するという手法です。プログラミングですから一定のルールで作成されているhtmlからなら簡単にスクレイピング出来ます。

スクレイピングしよう

スクレイピングプログラミング言語を使ってやるんですが僕はプログラマーでは無いのでこの分野においては完全な素人です。それを踏まえたうえで以下を読んでいただきたいと思います。

以下は僕の環境です。 PC:Windows7 言語:python2.7、php データベース:MySQL 使用ソフト:WebMatrixTerapad、HeidiSQL、Ampps

スクレイピング用にはpythonのバージョン2.7を使っています。現在バージョンは3まで出てるんですがWindows7の環境だといろいろ面倒なので2.7を使用。pythonのモジュールはBeautifulSoup、urllib2を使用。このあたりのインストールについては割愛させていただきます。僕なんか説明するよりGoogle先生のほうが詳しいです。

コードも一応公表してみます。何度も言いますがプログラミング素人です。見よう見まねで書いたクソコードなので怒らないでくださいね。

# -*- coding: utf-8 -*-
 
import sys,string, re, urllib, urllib2
from BeautifulSoup import BeautifulSoup

f = open("jbl_team_home201213.txt","a+")

for numb in ('482','486'):
    address = ('http://www.jbl.or.jp/schedule/2012-2013/boxscore/?g=T2012002G' + numb +'&t=T2012002')
    html = urllib2.urlopen(address).read()
    soup = BeautifulSoup(html)
    tables = soup.findAll('table')
    home = tables[1]
    trtr = home.findAll('tr')
    tdtdtd = trtr[1]
    period = tdtdtd.findAll('td')
    secondtable = tables[2]
    for tr in secondtable.findAll('tr')[-1:]:
        tds = tr.findAll('td')
        minu = tds[1].renderContents()
        tfgam = tds[4].renderContents()
        tpam = tds[6].renderContents()
        ftam = tds[8].renderContents()
        oreb = tds[10].renderContents()
        dreb = tds[11].renderContents()
        reb = tds[12].renderContents()
        ast = tds[13].renderContents()
        tov = tds[14].renderContents()
        stl = tds[15].renderContents()
        blk = tds[16].renderContents()
        perf = tds[17].renderContents()
        foulon = tds[18].renderContents()
        pts = tds[19].renderContents()
        entry = (minu,tfgam,tpam,ftam,oreb,dreb,reb,ast,tov,stl,blk,perf,foulon,pts,'201213' + numb)
    f.write( str(period) + str(entry) + "\n")

プログラミングに縁の無い方にとっては何のこっちゃって感じでしょうが、これを実行すると2012-13シーズンの開幕カードであるトヨタアルバルクvsリンク栃木の2試合をスクレイピングしています。ただしこれはホームのチームスタッツのみスクレイピングするコードです。

変数名の付け方がクソですがクソコードなので許してください。 えーとざっくり説明するとホームチーム

・クォーター毎の得点を取得 ・チームスタッツを取得

ということをやってます。 フィールドゴールに関してはPHPMySQLを使って表示する時に足し算してるので取得してません。 チーム名、クォーター毎の得点、時間、2ポイント試投数、成功数、3ポイント試投数、成功数、フリースロー・・・という感じですね。

for numb in ('482','486'): 上の482というのは以下URLの太字部分ですね。 http://www.jbl.or.jp/schedule/2012-2013/boxscore/?g=T2012002G482&t=T2012002 コードでは2試合しか入れてませんが全試合入れれば全ホームチーム側のチームスタッツを入手できます。 このURLの取得もスケジュールページからスクレイピングして取得してます。手打ちでリンク取得するのも面倒くさいので(^^

実際に削りとったデータがこれ。

[トヨタ自動車アルバルク, 29, 16, 25, 15, 85]('200', '27/49', '9/26', '4/12', '23', '32', '55', '17', '11', '6', '3', '16', '21', '85', '201213482')
[トヨタ自動車アルバルク, 21, 16, 34, 22, 93]('200', '24/48', '9/21', '18/22', '15', '35', '50', '16', '13', '5', '3', '24', '27', '93', '201213486')

最後の201213482という数字は僕個人があとでゲームIDとして使用するために作ってるだけなので気になさらず(^^ 何度も何度も言いますがクソコードです。もっと素晴らしいコードが書ける方は検索すればたくさん出てきます。 本職がプログラマの方なら「スクレイピング→整形→CSVMySQL」までの一連の流れを作れるはずです。 ※整形作業に関してはTerapadを使って置換→MySQLで取り込める形(CSV形式)にして保存しています。

終わりに

僕はクソコードしか作れないので苦戦していますが、プログラミングがわかる人(これから勉強しようという人)でバスケのスタッツに興味のある方はどんどんチャレンジして欲しいです。その時にこの記事が少しでも役立てばいいですし、この記事の目的はもっと日本国内リーグのスタッツが充実して、そこから派生するバスケのデータ分析などの分野が活性化して欲しいと思っているからです。

以上、駄文でしたがここまで読んでくださってありがとうございました。