Share This:
ちなみにデータ解析はデータを解析できる形に持っていくまでが全工程の九割を占めると言われている。実際私もこのスクレイピング&素性作成用スクリプトを作成するのに数週間はかけている*4。このスクリプトを無料で使える皆さんは幸運である。 スクレイピングとは. [:space:]./.馬身|[ア-ン-]+"))) race_result <- race_result[-5] # 馬名、馬齢、馬体重 race_result <- dplyr::mutate(race_result,horse_name=as.character(str_extract_all(race_result$`horse_name/age`,"[ァ-ヴー・]+"))) race_result <- dplyr::mutate(race_result,horse_age=as.character(str_extract_all(race_result$`horse_name/age`,"牡\\d+|牝\\d+|せん\\d+"))) race_result <- dplyr::mutate(race_result,horse_weight=as.character(str_extract_all(race_result$`horse_name/age`,"\\d{3}"))) race_result <- dplyr::mutate(race_result,horse_weight_change=as.character(str_extract_all(race_result$`horse_name/age`,"\\([\\+|\\-]\\d+\\)|\\([\\d+]\\)"))) race_result$horse_weight_change <- sapply(rm_round(race_result$horse_weight_change, extract=TRUE), paste, collapse="") race_result <- race_result[-4] # ジョッキー race_result <- dplyr::mutate(race_result,jockey=as.character(str_extract_all(race_result$`jockey/weight`,"[ぁ-ん一-龠]+\\s[ぁ-ん一-龠]+|[:upper:]. スクレイピングを行う際は、時間を空けるコーディングするなどその点に留意をして行ってください(最悪訴えられる可能性がありますが、こちらは一切の責任を取りません)。 # rvestによる競馬データのwebスクレイピング. ケイバファイブでは、競馬データの分析をwebスクレイピングで行おうと日々試行錯誤しております。環境づくりや手法について、備忘録的な意味で記事に残していこうと思います。 | Webサイトにアクセスする; 該当する箇所をメモしてエクセルに貼り付ける [:space:]./.馬身|[ア-ン-]+")))race_result <- race_result[-5], # 馬名、馬齢、馬体重race_result <- dplyr::mutate(race_result,horse_name=as.character(str_extract_all(race_result$`horse_name/age`,"[ァ-ヴー・]+")))race_result <- dplyr::mutate(race_result,horse_age=as.character(str_extract_all(race_result$`horse_name/age`,"牡\\d+|牝\\d+|せん\\d+")))race_result <- dplyr::mutate(race_result,horse_weight=as.character(str_extract_all(race_result$`horse_name/age`,"\\d{3}")))race_result <- dplyr::mutate(race_result,horse_weight_change=as.character(str_extract_all(race_result$`horse_name/age`,"\\([\\+|\\-]\\d+\\)|\\([\\d+]\\)")))race_result$horse_weight_change <- sapply(rm_round(race_result$horse_weight_change, extract=TRUE), paste, collapse="")race_result <- race_result[-4], # ジョッキーrace_result <- dplyr::mutate(race_result,jockey=as.character(str_extract_all(race_result$`jockey/weight`,"[ぁ-ん一-龠]+\\s[ぁ-ん一-龠]+|[:upper:]. ブログを報告する, 【競馬】rvestでyahoo競馬にある過去のレース結果をスクレイピングしてみた。, https://keiba.yahoo.co.jp/schedule/list/2016/?month=, 【競馬】【再実行】rvestでyahoo競馬にある過去のレース結果をスクレイピングしてみた。, 【日次GDP】日次GDP推計に使用する経済統計を統計ダッシュボードから集めてみた。, 【競馬】【やり直し】rvestでyahoo競馬にある過去のレース結果をスクレイピングしてみた。. スクレイピングとは、Webページの情報を取得することができる技術のことです。例えば、日経平均のデータを毎日エクセルに記録したいとします。でもこれを毎日. プログラミングをしましょう。pythonスクレイピングで競馬のデータ収集を行ってみます。スクレイピングを使えば枠、人気、馬体重、距離、コース、調教タイムなどなど多くのデータをサイトから集めることができます。 #install.packages("rvest") [ァ-ヶー]+")))race_result <- race_result[-4], # オッズと人気race_result <- dplyr::mutate(race_result,odds=as.character(str_extract_all(race_result$`popularity/odds`,"\\(.+\\)")))race_result <- dplyr::mutate(race_result,popularity=as.character(str_extract_all(race_result$`popularity/odds`,"\\d+[^(\\d+.\\d)]")))race_result$odds <- sapply(rm_round(race_result$odds, extract=TRUE), paste, collapse="")race_result <- race_result[-4], ここまででデータは取得できたわけなのですが、そのデータは綺麗なものにはなっていません。 上のコードでは、その整形作業を行っています。現在、取得したデータは以下のようになっています。, ご覧のように、\nが入っていたり、通過順位と上り3ハロンのタイムが一つのセルに入っていたりとこのままでは分析ができません。不要なものを取り除いたり、データを二つに分割する作業が必要になります。今回の記事ではこの部分について詳しくは説明しません。この部分は正規表現を駆使する必要がありますが、私自身全く詳しくないからです。今回も手探りでやりました。, # レース情報race_date <- race1 %>% html_nodes(xpath = "//div[@id = 'raceTitName']/p[@id = 'raceTitDay']") %>% html_text()race_name <- race1 %>% html_nodes(xpath = "//div[@id = 'raceTitName']/h1[@class = 'fntB']") %>% html_text(), race_result <- dplyr::mutate(race_result,race_date=as.character(str_extract_all(race_date,"\\d+年\\d+月\\d+日")))race_result <- dplyr::mutate(race_result,race_name=as.character(str_replace_all(race_name,"\\s",""))), ## ファイル格納if (k ==1 && i == 1){ dataset <- race_result} else { dataset <- rbind(dataset,race_result)}# if文の終わり} # iループの終わり, 最後に、レース日時とレース名を抜き出し、データを一時的に格納するコードとcsvファイルに書き出すコードを書いて終了です。完成データセットは以下のような状態になっています。, 以上です。次回はこのデータセットを使用して、分析を行っていきます。次回までには1994年からのデータを全てスクレイピングしてきます。, 上述したスクリプトを用いて、スクレイピングを行ったところエラーが出ました。どうやらレース結果の中には強風などで中止になったものも含まれているらしく、そこでエラーが出る様子(race_resultがcharacter(0)になってしまう)。なので、この部分を修正したスクリプトを以下で公開しておきます。こちらは私の PC環境では正常に作動しています。, #install.packages("rvest")#if (!require("pacman")) install.packages("pacman")install.packages("beepr")pacman::p_load(qdapRegex)library(rvest)library(stringr)library(dplyr)library(beepr), # pathの設定setwd("C:/Users/assiy/Dropbox/競馬統計解析"), for(year in 1994:2018){ # yahoo競馬のレース結果一覧ページの取得for (k in 1:12){ keiba.yahoo <- read_html(str_c("https://keiba.yahoo.co.jp/schedule/list/", year,"/?month=",k))race_url <- keiba.yahoo %>% html_nodes("a") %>% html_attr("href") # 全urlを取得, Sys.sleep(10) print(str_c("現在、", year, "年", k, "月", i,"番目のレースの保存中です")), race1 <- read_html(str_c("https://keiba.yahoo.co.jp",race_url[i])) # レース結果のurlを取得, # レースが中止でなければ処理を実行if (identical(race1 %>% html_nodes(xpath = "//div[@class = 'resultAtt mgnBL fntSS']") %>% html_text(),character(0)) == TRUE){ # レース結果をスクレイピング race_result <- race1 %>% html_nodes(xpath = "//table[@id = 'raceScore']") %>% html_table() race_result <- do.call("data.frame",race_result) # リストをデータフレームに変更 colnames(race_result) <- c("order","frame_number","horse_number","horse_name/age","time/margin","passing_rank/last_3F","jockey/weight","popularity/odds","trainer") # 列名変更 # 通過順位と上り3Fのタイム race_result <- dplyr::mutate(race_result,passing_rank=as.character(str_extract_all(race_result$`passing_rank/last_3F`,"(\\d{2}-\\d{2}-\\d{2}-\\d{2})|(\\d{2}-\\d{2}-\\d{2})|(\\d{2}-\\d{2})"))) race_result <- dplyr::mutate(race_result,last_3F=as.character(str_extract_all(race_result$`passing_rank/last_3F`,"\\d{2}\\.\\d"))) race_result <- race_result[-6] # タイムと着差 race_result <- dplyr::mutate(race_result,time=as.character(str_extract_all(race_result$`time/margin`,"\\d\\.\\d{2}\\.\\d|\\d{2}\\.\\d"))) race_result <- dplyr::mutate(race_result,margin=as.character(str_extract_all(race_result$`time/margin`,"./.馬身|.馬身|. 競馬のデータはほぼテーブルで表示されるから、テーブルのスクレイピングを把握すれば、簡単に取得できますね。 最近、Octoparseは初心者への「 Hello World 」を用意し、テストサイトを使って、スクレイピングの方法を紹介しています。 競馬のレース結果を的中させるモデルを作ろうということで研究をはじめました。まずはデータを自分で取ってくるところからやろうとおもいます。どこからデータを取ってくるのかという点が重要になるわけですが、データ先としてはdatascisotistさんがまとめられた非常にわかりやすい記事があります。どこからデータが取れるのかというと大きく分けて二つで、①JRA提供のJRA-VAN、電子競馬新聞でおなじみの?JRJDといったデータベース、②netkeiba、yahoo競馬とといった競馬情報サイトとなってます。②の場合は自分でコードを書き、スクレイピングを行う必要があります。今回はyahoo競馬のデータをWebスクレイピングで落としてきたいと思います。Pythonは使えないのでRでやります。Rでスクレイピングを行うパッケージとしては、rvest, httr, XMLがありますが、今回は1番簡単に使えるrvestを用います。yahoo競馬では以下のように各レース結果が表にまとめられています(5月の日本ダービーの結果)。, 各馬のざっくりとした特徴やレース結果(通過順位等含む)、オッズが掲載されています。とりあえず、このぐらい情報があれば良いのではないかと思います(オッズの情報はもう少し欲しいのですが)。ただ、今後は少しずつ必要になった情報を拡充していこうとも思っています。1986年までのレース結果が格納されており、全データ数は50万件を超えるのではないかと思っています。ただ、単勝オッズが利用できるのは1994年からのようなので今回は1994年から直近までのデータを落としてきます。今回のゴールは、このデータをcsvファイル or SQLに格納することです。, Rvestとは、webスクレイピングパッケージの一種でdplyrでおなじみのHadley Wickhamさんによって作成されたパッケージです。たった数行でwebスクレイピングができる優れものとなっており、操作が非常に簡単であるのが特徴です。今回は以下の本を参考にしました。, そもそも、htmlも大学一年生にやった程度でほとんど忘れていたのですが、この本はそこも非常にわかりやすく解説されており、非常に実践的な本だと思います。, さて、実際にyahoo競馬からデータを落としてみたいと思います。コードは以下のようになっております。ご留意頂きたいのはこのコードをそのまま使用してスクレイピングを行うことはご遠慮いただきたいという事です。webスクレイピングは高速でサイトにアクセスするため、サイトへの負荷が大きくなる可能性があります。スクレイピングを行う際は、時間を空けるコーディングするなどその点に留意をして行ってください(最悪訴えられる可能性がありますが、こちらは一切の責任を取りません)。, #install.packages("rvest")#if (!require("pacman")) install.packages("pacman")pacman::p_load(qdapRegex)library(rvest)library(stringr)library(dplyr), 使用するパッケージはqdapRegex、rvest、stringr、dplyrです。qdapRegexはカッコ内の文字を取り出すために使用しています。, keiba.yahoo <- read_html(str_c("https://keiba.yahoo.co.jp/schedule/list/2016/?month=",k))race_url <- keiba.yahoo %>% html_nodes("a") %>% html_attr("href") # 全urlを取得, # レース結果のをurlを取得race_url <- race_url[str_detect(race_url, pattern="result")==1] # 「result」が含まれるurlを抽出, まず、read_htmlでyahoo競馬のレース結果一覧のhtml構造を引っ張ってきます(リンクは2016年1月の全レース)。ここで、kと出ているのは月を表し、k=1であれば2016年1月のレース結果を引っ張ってくるということです。keiba.yahooを覗いてみると以下のようにそのページ全体のhtml構造が格納されているのが分かります。, race_urlにはyahoo.keibaのうちの2016年k月にあった全レース結果のリンクを格納しています。html_nodeとはhtml構造のうちどの要素を引っ張るかを指定し、それを引っ張る関数で、簡単に言えばほしいデータの住所を入力する関数であると認識しています(おそらく正しくない)。ここではa要素を引っ張ることにしています。注意すべきことは、html_nodeは欲しい情報をhtml形式で引っ張ることです。なので、テキストデータとしてリンクを保存するためにはhtml_attrを使用する必要があります。html_attrの引数として、リンク属性を表すhrefを渡しています。これでレース結果のurlが取れたと思いきや、実はこれでは他のリンクもとってしまっています。一番わかりやすいのが広告のリンクです。こういったリンクは除外する必要があります。レース結果のurlには"result"が含まれているので、この文字が入っている要素だけを抽出したのが一番最後のコードです。, for (i in 1:length(race_url)){race1 <- read_html(str_c("https://keiba.yahoo.co.jp",race_url[i])) # レース結果のurlを取得, # レース結果をスクレイピングrace_result <- race1 %>% html_nodes(xpath = "//table[@id = 'raceScore']") %>% html_table()race_result <- do.call("data.frame",race_result) # リストをデータフレームに変更colnames(race_result) <- c("order","frame_number","horse_number","horse_name/age","time/margin","passing_rank/last_3F","jockey/weight","popularity/odds","trainer") # 列名変更, さて、いよいよレース結果のスクレイピングを行います。さきほど取得したリンク先のhtml構造を一つ一つ取得し、その中で必要なテキスト情報を引っ張るという作業をRに実行させます(なのでループを使う)。race_1にはあるレース結果ページのhtml構造が格納されおり、race_resultにはその結果が入っています。html_nodesの引数に入っているxpathですが、これはXLMフォーマットのドキュメントから効率的に要素を抜き出す言語です。先ほど説明した住所のようなものと思っていただければ良いと思います。その横に書いてある「//table[@id = 'raceScore']」が住所です。これはwebブラウザから簡単に探すことができます。Firefoxの説明になりますが、ほかのブラウザでも同じような機能があると思います。スクレイプしたい画面でCtrl+Shift+Cを押すと下のような画面が表示されます。, このインスペクターの横のマークをクリックすると、カーソルで指した部分のhtml構造(住所)が表示されます。この場合だと、レース結果はtable属性のidがraceScoreの場所に格納されていることが分かります。なので、上のコードではxpath=のところにそれを記述しているのです。そして、レース結果は表(table)形式でドキュメント化されているので、html_tableでごっそりとスクレイプしました。基本的にリスト形式で返されるので、それをデータフレームに変換し、適当に列名をつけています。, # 通過順位と上り3Fのタイムrace_result <- dplyr::mutate(race_result,passing_rank=as.character(str_extract_all(race_result$`passing_rank/last_3F`,"(\\d{2}-\\d{2}-\\d{2}-\\d{2})|(\\d{2}-\\d{2}-\\d{2})|(\\d{2}-\\d{2})")))race_result <- dplyr::mutate(race_result,last_3F=as.character(str_extract_all(race_result$`passing_rank/last_3F`,"\\d{2}\\.\\d")))race_result <- race_result[-6], # タイムと着差race_result <- dplyr::mutate(race_result,time=as.character(str_extract_all(race_result$`time/margin`,"\\d\\.\\d{2}\\.\\d|\\d{2}\\.\\d")))race_result <- dplyr::mutate(race_result,margin=as.character(str_extract_all(race_result$`time/margin`,"./.馬身|.馬身|. 先にまとめた「Pythonクローリング&スクレイピング[増補改訂版]―データ収集・解析のための実践開発ガイドー」加藤耕太・著 の第2章までの知識の実践として、Pythonを利用した競馬のレース結果のクローリング・スクレイピングを行う。なおコードに関しては同書P71のサンプルコードを大いに参考にしている。 今回クローリング・スクレイピングの対象とするのは競馬情報サイトnetkeibaの地方競馬カテゴリの上部からリンクされているここ数日の開催の結果表である(数日たったら消えるっぽい?コ… [ァ-ヶー]+"))) race_result <- race_result[-4] # オッズと人気 race_result <- dplyr::mutate(race_result,odds=as.character(str_extract_all(race_result$`popularity/odds`,"\\(.+\\)"))) race_result <- dplyr::mutate(race_result,popularity=as.character(str_extract_all(race_result$`popularity/odds`,"\\d+[^(\\d+.\\d)]"))) race_result$odds <- sapply(rm_round(race_result$odds, extract=TRUE), paste, collapse="") race_result <- race_result[-4] # レース情報 race_date <- race1 %>% html_nodes(xpath = "//div[@id = 'raceTitName']/p[@id = 'raceTitDay']") %>% html_text() race_name <- race1 %>% html_nodes(xpath = "//div[@id = 'raceTitName']/h1[@class = 'fntB']") %>% html_text() race_result <- dplyr::mutate(race_result,race_date=as.character(str_extract_all(race_date,"\\d+年\\d+月\\d+日"))) race_result <- dplyr::mutate(race_result,race_name=as.character(str_replace_all(race_name,"\\s",""))) ## ファイル貯めるのかく if (k == 1 && i == 1 && year == 1994){ dataset <- race_result } else { dataset <- rbind(dataset,race_result) } # if文2の終わり} # if文1の終わり} # iループの終わり} # kループの終わり beep() } # yearループの終わり write.csv(dataset,"race_result.csv", row.names = FALSE), これを回すのに16時間かかりました(笑)データ数は想定していたよりは少なく、97939になりました。, osashimixさんは、はてなブログを使っています。あなたもはてなブログをはじめてみませんか?, Powered by Hatena Blog

東京オリンピック Cm, 戸田球場 チケット 売り切れ, 体に悪い ラーメン ランキング, 埼玉県 サッカー 高校 順位, フェニックス レーティング 反映, Dカード 公共料金 ポイント還元率, 甲子園 今日の試合, 坂口健太郎 ドラマ, ナラタージュ 小説 名言, 最新 チョコレート菓子, 青山学院大学 ジャニーズjr, 湾岸戦争 中東戦争, Ur賃貸 一人暮らし, 石川歩 成績, 日ハム Ob選手, コウノドリ ゲスト 一覧, アルゼンチン人 彼女, 人口密度 求め方, 20プリウス 警告灯 一覧, アメリカ 大統領 拒否権, コロナ 少年サッカー, 白日 ドラム 解説, 陽月華 本名, 発達 障害 受信 料, サバイバー 日本版 動画, ウイニングポスト9 ヒシアマゾン 引退時期, スポーツ選手 自宅, エリザベス女王杯 1999, サバイバルファミリー 鹿児島 どこ, 田村龍弘 年俸, 東 福岡 対 飯塚, 競馬 天気 影響, 三国 五 虎将, 海上自衛隊 潜水艦 給料,

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です