Lean Baseball

No Engineering, No Baseball.

Pythonを用いたWebスクレイピングの開発ノウハウ〜スポーツデータの場合(野球風味)

クローラー/Webスクレイピング Advent Calendar 2016 - Qiitaのクローザーとしてマウンドに立ちます@shinyorke(しんよーく)ともうします.

このエントリーではみんな大好きな野球(メジャーリーグ)を題材に,

  • Webスクレイパーを開発するコツ
  • スポーツデータ特有の困った話
  • メジャーリーグベースボールのスクレイパーをガチで開発した話

を,自分の実体験を元に紹介します.

年末年始?来年とかに, 「俺もスポーツデータで機械学習やるぞ!」 という方(と自分)の参考になればと幸いです.*1

というわけでプレイボール⚾

対象読者&取りあつかわないこと

対象読者

  • スクレイピングおよびPythonのプログラミング初〜中級者
  • 何かしらのテーマ,特にスポーツでWebスクレイピングをされたい方
  • データに強いPythonでスクレイピング&分析したい方
  • とにかくスポーツ,特に球技が大好きだ(野球に限らず)
  • 野球のルールとデータの意味を知っている(誰が出ていて,どっちが勝ってるか分かる程度でOK)

取りあつかわないこと

特にクローラー(scrapyのノウハウとか)について期待している方は別のエントリーをご覧頂ければと思います.*2

  • 特定のサイト・データを周期的・自動的に取得する,つまりクローラーのの解説とか各論
  • Python以外の言語・ライブラリの話題
  • 野球・メジャーリーグのデータおよび指標の解説

Starting Member

  • Pythonを用いたWebスクレイパー開発の勘どころ
  • スポーツデータをスクレイピングする際のコツとノウハウ
  • メジャーリーグベースボールのデータセットをスクレイピングする(pitchpx)

Pythonを用いたWebスクレイパー開発の勘どころ

スポーツに関係なく,PythonでWebスクレイパーの開発をする際の流れを元に勘どころを紹介します.

ちなみにこれは完全に我流です(が自信はある).

Webスクレイパー開発の流れ

私はスクレイピングを行う際,必ず以下の作業&定義を決めてから開発を行っています.

  • スクレイピングの対象ページを眺める&コードを追う
  • 要件を決める
  • ライブラリ(もしくはフレームワーク)の構成を決める
    • requests
    • Beautiful Soup
    • scrapy
    • pandas

スクレイピングの対象ページを眺める&コードを追う

まずこれをしないと何も始まりません!

スクレイピングしたいページをChromeの開発者ツール(Safari・Firefoxなど好きなブラウザでOK)を用いて,

眺める

ここでは, スクレイピングする必要が無ければスクレイピング以外の手段を使うという事を前提に調べていきます.

  • APIの有無
  • オープンデータや公式データ無いかな?

を地道に調べます.

たとえばWikipediaはスクレイピングしなくても, 公式のデータベースがあったりするので必要ないな,とわかるだけでも無駄なプログラミングをせずに済みますし,ライセンスなどの問題に当たる必要がなくなります.

コードを追う

  • HTMLの構成, 特にデータの出どころ
  • CSSのルールや名前
  • サイトの構造

などを辿っていきます.

重要なポイントはやっぱりデータの出どころで,

  • HTMLに直接書いている場合(tableタグとかdivタグ)はHTMLをスクレイピングするツールを使う
  • AngularやReactなどのシングルページアプリケーションやJQuery等でAPIを呼び出してるアプリの場合はJavaScriptをスクレイピングする仕組みを使う

要するに,対象のデータがHTMLなのかJSなのかを見極める事を重点的に行います.

要件を決める

(スクレイピングに限らず)やみくもにコーディングすると目的がどっか行ったりするので,要件を決めます.

私は目的,もっといえば「なぜスクレイピングするか」のストーリーをちゃんと作りたい人なので,

  • リーンキャンバスやインセプションデッキなどのフレームワークを使って整理
  • フレームワークまで頑張りたくない時は実現したい姿をお絵描きする

ということをしています.

とはいえ,「お勉強のためにスクレイピングしたい」「いやまあ使い捨てのツールだし」っていう場合は,

  • 環境や動作条件(Pythonのバージョン,出力フォーマットなど)をメモる
  • なんちゃってで動くWebスクレイパーを作る,平たくいうとプロトタイピングする

というのも良いでしょう.

なお,私は恒常的につかうWebスクレイパーを作りたかったのでインセプションデッキに要件とゴールを書きました.

インセプションデッキ(一部抜粋)

Webスクレイパーに加え,分析環境も作ってたので内容が若干煩雑かも.

f:id:shinyorke:20161225160046j:plain

f:id:shinyorke:20161225160216j:plain

f:id:shinyorke:20161225160231j:plain

ライブラリ(もしくはフレームワーク)の構成を決める

ここでようやっとライブラリやフレームワークを選ぶ段階に入ります.

Pythonの場合,Webスクレイピングの手段として,

  • 素のPython(urllibなど)を使う
  • 便利なHTTPクライアント「requests」
  • HTMLをスクレイピングするなら「Beautiful Soup」
  • Webクローラーを含めてオールインワンで開発「scrapy」
  • 分析しながらカジュアルにスクレイピング&Dataframe化する「pandas」のread_htmlメソッド

という5つの手段があります(他にもあると思うけど知らない).

それぞれの強みと利点を簡単に紹介します.

素のPython(urllibなど)を使う

  • (当たり前だが)ライブラリの導入がいらない
  • 好きなようになんでも書ける
  • なんでも書ける!ということは自分で書くコードの総量が増える&メンテナンスが煩雑に
  • Pythonそのものの勉強目的を除きオススメしません!*3

便利なHTTPクライアント「requests」

github.com

  • HTTP Request/Responseを人間らしくカジュアルに扱える神ライブラリ
  • モジュールやメソッドがかなり直感的で使いやすい
  • ちょっとリッチなHTMLなどをスクレイピングするときにはコード量が増える印象
  • JSON/XMLなどで返すAPIを扱うときは一番ラク&最強です!

HTMLをスクレイピングするなら「Beautiful Soup」

Beautiful Soup Documentation — Beautiful Soup 4.4.0 documentation

  • PythonでWebスクレイピングといえば!の代表格でとても扱いやすい!
  • 特定のタグの捜索や正規表現(find/find_all)に加えてCSSセレクタ(select)での特定や抽出ができる
  • HTMLのWebスクレイピングはまずbeautiful soupで間違いない
  • クローラーに必要な機能(ファイル/データベース出力,定期的なクロール)は自前で実装が必要,そこまで必要になったらscrapyで
  • xpathには対応していない,これもやりたくなったらscrapyかな

Webクローラーを含めてオールインワンで開発「scrapy」

Scrapy | A Fast and Powerful Scraping and Web Crawling Framework

  • Webスクレイピング/クローラー界のWebフレームワーク,と呼ぶべき王様!
  • ページの捜索からスクレイピング,出力までを一気通貫に作れるかつ,それぞれの層が抽象的に分かれているため分散開発(複数人で開発)も容易
  • xpathにも対応かつJSのスクレイピングも可能
  • フレームワーク特有の「方言*4」があり,Python初心者・初学者にはオススメが難しい
  • 大きめのサイトをスクレイピング/クロールするのには向いているが,小さいサイトや使い捨て目的の場合は冗長になりがち(アプリの規模的に)

分析しながらカジュアルにスクレイピング&Dataframe化する「pandas」のread_htmlメソッド

pandas.read_html

  • pandasのDataframeをすぐ作りたいかつ,ページがtableタグで構成されているときは一番手っ取り早い!
  • データ型まで保証はしてくれませんが必要なDataframeが1行で書けるのはかなり強力
  • 前処理(ゴミを取り除く,欠損値対応など)を地道にできる人はさっさとpandasでやっちゃうのが良さそう

なお,このブログでも事例を紹介させてもらいました(野球ネタです).

shinyorke.hatenablog.com

どの手段が一番オススメか!?

私個人の意見としては,

  • RESTful APIを叩くだけならrequests
  • 一時的にHTMLをスクレイピングするならBeautiful Soup
  • クローラーを作る必要がある要件だったらscrapy一択
  • Try and Errorで分析しながらやるor手早くまとめるならpandas.read_html
  • 迷ったらBeautiful Soup!

ですね.

何をやるのにもscrapyは最強なのですが,迷った時はBeautiful Soupを使っています,欠点(xpath使えない,クローラー化が面倒)については回避の方法もありますし,何よりライブラリが完成度高く,事例がたくさんあるので個人的にはBeautiful Soup推しです.

と,いいつつ最近はscrapyの方が使う機会増えてますけどねw*5

スポーツデータをスクレイピングする際のコツとノウハウ

お待ちかね,スポーツデータの話です.

野球やサッカーといったデータを使った分析事例が増えていたり,自分でもやる方も増えている印象があり(火付け役の一人として)とても嬉しいのですが,スクレイピングそのものが辛くなるようなハマりどころが存在します.

いくつか事例(≒僕の黒歴史)を紹介します.

ページ構造/APIのインターフェースが不完全

  • スクレイピングの後にやりたいことにたいして,データが見当たらないもしくは別ページ・APIに存在する
  • 例えば野球の場合,指標の計算で盗塁死(cs)が欲しい!と思ってもデータが無かったり
  • 別サイトからスクレイピングする,盗塁死が無くても計算可能な近似式を使うなどで回避
  • Webスクレイパーを開発終了後に気がつくので本当にたちが悪い!(涙目)

データ・指標に関する仕様が見当たらない

  • 「知ってて当然だよね?」と言わんばかりに指標の説明などが全く持ってない!
  • 距離や長さがメートルなのかフィートなのか?とかそのレベル
  • 本物の一球速報サイトや海外の文献を漁って仕様を類推,確かめながら作るなどして対応
  • スピードガンやPitch f/xは仕様がそもそもガラパゴスだという事を把握(学び)野球専用の機械だししょーがない.

計算が合わない

  • 前処理・指標計算の結果が実際の結果と合わない
  • 前述の「インターフェース不完全」「仕様が謎」問題から起こる不幸
  • こればっかりはスポーツ(野球)のドメイン知識を駆使して地道に解くしか無い

処方箋

そんな不幸を避けるためには,

要件をちゃんと作る・書く

ガッツリな仕様は無くてもやっぱ転ばぬ先の杖は要件かなと.

  • データの不完全性や仕様を予め把握
  • どこにデータがあるの?とかフォーマットはHTML?JSなの?とか
  • インセプションデッキとかお絵かきとか面倒くさいと思うでしょう?事前に整理することによって気がつくことがあるんですよ!!!

ドメイン知識をつける

スポーツデータに限った話ではないですが本当に重要.

  • 野球なら野球、サッカーならサッカーのドメイン知識をこれでもかっ!ってぐらいつける
  • ルール、データの種類から対象リーグのトレンドだったり傾向だったり.
  • 野球の場合は上記に加えてセイバーメトリクスの基礎も覚えるとなお良い.
  • 「オレ,審判とかスコアラーできちゃう!?」ぐらいに磨けば完璧
  • 球場やTVで試合みる延長線上でデータをスクレイピングしたり分析できたりすると思うなよ!

メジャーリーグベースボールのデータセットをスクレイピングする(pitchpx)

一個の事例として.

昨年末〜今年にかけて,MLBの一球速報データをスクレイピングしてデータセットにするWebスクレイパー(コマンドラインツール)を自作しました!

github.com

こちらで何ができるか?というと,

  • 2007年以降のMLB全試合(プレーオフ含む)の一球データをCSVとして取得
  • 投球,打席の結果がメイン
  • ついでに出場選手や審判のデータセットも含む

をコマンドラインでサクッととれます.

事例についてはこのブログやPyCon JP 2016で発表させてもらいました.

使いたい方や気になる方はぜひご覧ください!

shinyorke.hatenablog.com

shinyorke.hatenablog.com

qiita.com

なお開発の時のtipsはこんな感じ,

  • Python 3専用で作った
  • Beautiful Soupベースで開発
  • 本当はクローラーにしたかったのでscrapyを使うつもりだったが,開発当時Python3を正式サポートしていなかったこと, scrapyに慣れていなかった事もあり断念
  • 初速はテスト無しで開発,ある程度安定した後テストを書いた&CIを入れた

好きな言語・好きな開発手法を思いっきりできたので気持ちよかったです.

まとめ

そら(Webスクレイパーを書くならPythonが最強で)そう(事前の下調べや要件づくり,ドメイン知識が大切に)よ(決まっているじゃないか)

私がPythonistaということもありますが,ちょっとしたWebスクレイパーはPythonを使うのがベストかなと思います.

あとは最近書いていませんが,Rubyのnokogiriとかもいいよなー,とか.

その他の言語については自分自身スクレイピングの知見が無いので是非ともフィードバックを頂けると幸いです!

長文となりましたが最後まで読んでいただきありがとうございました!

(Appendix)参考文献

今回のブログを書くにあたり参考にした文献など.

書籍(Python)

オライリーのWebスクレイピング本は名著です&初学者の方には独習Python入門のスクレイピングのページが良いです(beautiful soupの事例です)

PythonによるWebスクレイピング 第2版

PythonによるWebスクレイピング 第2版

  • 作者: Ryan Mitchell,嶋田健志,黒川利明
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2019/03/26
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログを見る

独習Python入門――1日でプログラミングに強くなる!

独習Python入門――1日でプログラミングに強くなる!

その他最近スクレイピングの本が出ていますが...まだ読んでないので良い本があれば教えて欲しい.

書籍(野球・サッカーのドメイン知識)

主に野球・サッカーのドメイン知識をつけるなら!

マネー・ボール〔完全版〕 (ハヤカワ・ノンフィクション文庫)

マネー・ボール〔完全版〕 (ハヤカワ・ノンフィクション文庫)

ビッグデータ・ベースボール 20年連続負け越し球団ピッツバーグ・パイレーツを甦らせた数学の魔法

ビッグデータ・ベースボール 20年連続負け越し球団ピッツバーグ・パイレーツを甦らせた数学の魔法

サッカー データ革命 ロングボールは時代遅れか

サッカー データ革命 ロングボールは時代遅れか

公認野球規則〈2016〉Official Baseball Rules

公認野球規則〈2016〉Official Baseball Rules

野球規則を正しく理解するための野球審判員マニュアル―規則適用上の解釈について

野球規則を正しく理解するための野球審判員マニュアル―規則適用上の解釈について

Analyzing Baseball Data with R (Chapman & Hall/CRC The R Series Book 14) (English Edition)

Analyzing Baseball Data with R (Chapman & Hall/CRC The R Series Book 14) (English Edition)

4‐2‐3‐1―サッカーを戦術から理解する (光文社新書)

4‐2‐3‐1―サッカーを戦術から理解する (光文社新書)

ブログ・スライドなど

主にamacbeeさんのブログ・スライドを参考にさせてもらいました.

amacbee.hatenablog.com

qiita.com

qiita.com

speakerdeck.com

*1:本題と関係ありませんが最近スポーツhackしたい方が増えているので何かコミュニティ作る&イベントやろうと思ってます

*2:日本プロ野球用に作ってるけど事情により非公開(察し)

*3:言語そのものの勉強だとしても,やるなら一回でいいと思う

*4:PythonでのDjango,RubyでのRailsを覚えるときのような「言語とは関係ないクセ」があるということです

*5:自分が慣れてきたのと,最初からクローラー化する前提での開発が多いのでscrapyを選択しています