% 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 ケイバファイブでは、競馬データの分析を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:]. [: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:]. Webサイトにアクセスする; 該当する箇所をメモしてエクセルに貼り付ける #install.packages("rvest") 競馬のレース結果を的中させるモデルを作ろうということで研究をはじめました。まずはデータを自分で取ってくるところからやろうとおもいます。どこからデータを取ってくるのかという点が重要になるわけですが、データ先としては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`,"./.馬身|.馬身|. ウルトラマン ハヤタ 事故, 富士ステークス 過去 2020, 杉本昌隆 師匠, 朝ドラ 主題歌 歌詞, 長谷部誠 佐藤ありさ 結婚式, イノセンス ドラマ あらすじ, 巨人ファン ジャニーズ, エルコンドルパサー 凱旋門賞, Nhk 受信料 生活保護 返金, 最後から二番目の恋 再放送 2019, Nhk受信料 払えない シングルマザー, 野木亜紀子 名言, ミノンメン セット, コウノドリ 3 主題歌, 戦争映画 感想, 坂口涼太郎 歌, 石川県 社会人サッカー, サウジアラビア 原油, 阪神 歴代開幕投手, 1996 エリザベス女王杯, フレッド キリスト トランプ, 愛知県高校サッカー ツイッター, 清原翔 綾野剛 米津玄師, ライフスタイルカレッジ オープニング, テイエムオペラオー 繁殖, 長野博 ティガ なんj, 戦争ドラマ 2019, 千葉 クラブ チーム, ..."> % 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 ケイバファイブでは、競馬データの分析を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:]. [: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:]. Webサイトにアクセスする; 該当する箇所をメモしてエクセルに貼り付ける #install.packages("rvest") 競馬のレース結果を的中させるモデルを作ろうということで研究をはじめました。まずはデータを自分で取ってくるところからやろうとおもいます。どこからデータを取ってくるのかという点が重要になるわけですが、データ先としては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`,"./.馬身|.馬身|. ウルトラマン ハヤタ 事故, 富士ステークス 過去 2020, 杉本昌隆 師匠, 朝ドラ 主題歌 歌詞, 長谷部誠 佐藤ありさ 結婚式, イノセンス ドラマ あらすじ, 巨人ファン ジャニーズ, エルコンドルパサー 凱旋門賞, Nhk 受信料 生活保護 返金, 最後から二番目の恋 再放送 2019, Nhk受信料 払えない シングルマザー, 野木亜紀子 名言, ミノンメン セット, コウノドリ 3 主題歌, 戦争映画 感想, 坂口涼太郎 歌, 石川県 社会人サッカー, サウジアラビア 原油, 阪神 歴代開幕投手, 1996 エリザベス女王杯, フレッド キリスト トランプ, 愛知県高校サッカー ツイッター, 清原翔 綾野剛 米津玄師, ライフスタイルカレッジ オープニング, テイエムオペラオー 繁殖, 長野博 ティガ なんj, 戦争ドラマ 2019, 千葉 クラブ チーム, ..." /> % 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 ケイバファイブでは、競馬データの分析を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:]. [: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:]. Webサイトにアクセスする; 該当する箇所をメモしてエクセルに貼り付ける #install.packages("rvest") 競馬のレース結果を的中させるモデルを作ろうということで研究をはじめました。まずはデータを自分で取ってくるところからやろうとおもいます。どこからデータを取ってくるのかという点が重要になるわけですが、データ先としては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`,"./.馬身|.馬身|. ウルトラマン ハヤタ 事故, 富士ステークス 過去 2020, 杉本昌隆 師匠, 朝ドラ 主題歌 歌詞, 長谷部誠 佐藤ありさ 結婚式, イノセンス ドラマ あらすじ, 巨人ファン ジャニーズ, エルコンドルパサー 凱旋門賞, Nhk 受信料 生活保護 返金, 最後から二番目の恋 再放送 2019, Nhk受信料 払えない シングルマザー, 野木亜紀子 名言, ミノンメン セット, コウノドリ 3 主題歌, 戦争映画 感想, 坂口涼太郎 歌, 石川県 社会人サッカー, サウジアラビア 原油, 阪神 歴代開幕投手, 1996 エリザベス女王杯, フレッド キリスト トランプ, 愛知県高校サッカー ツイッター, 清原翔 綾野剛 米津玄師, ライフスタイルカレッジ オープニング, テイエムオペラオー 繁殖, 長野博 ティガ なんj, 戦争ドラマ 2019, 千葉 クラブ チーム, ..." /> 競馬データ スクレイピング

BLOG

ブログ

競馬のデータはほぼテーブルで表示されるから、テーブルのスクレイピングを把握すれば、簡単に取得できますね。 最近、Octoparseは初心者への「 Hello World 」を用意し、テストサイトを使って、スクレイピングの方法を紹介しています。 先にまとめた「Pythonクローリング&スクレイピング[増補改訂版]―データ収集・解析のための実践開発ガイドー」加藤耕太・著 の第2章までの知識の実践として、Pythonを利用した競馬のレース結果のクローリング・スクレイピングを行う。なおコードに関しては同書P71のサンプルコードを大いに参考にしている。 今回クローリング・スクレイピングの対象とするのは競馬情報サイトnetkeibaの地方競馬カテゴリの上部からリンクされているここ数日の開催の結果表である(数日たったら消えるっぽい?コ… プログラミングをしましょう。pythonスクレイピングで競馬のデータ収集を行ってみます。スクレイピングを使えば枠、人気、馬体重、距離、コース、調教タイムなどなど多くのデータをサイトから集めることができます。 スクレイピングとは. | ブログを報告する, 【競馬】rvestでyahoo競馬にある過去のレース結果をスクレイピングしてみた。, https://keiba.yahoo.co.jp/schedule/list/2016/?month=, 【競馬】【再実行】rvestでyahoo競馬にある過去のレース結果をスクレイピングしてみた。, 【日次GDP】日次GDP推計に使用する経済統計を統計ダッシュボードから集めてみた。, 【競馬】【やり直し】rvestでyahoo競馬にある過去のレース結果をスクレイピングしてみた。. [ァ-ヶー]+"))) 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 ケイバファイブでは、競馬データの分析を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:]. [: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:]. Webサイトにアクセスする; 該当する箇所をメモしてエクセルに貼り付ける #install.packages("rvest") 競馬のレース結果を的中させるモデルを作ろうということで研究をはじめました。まずはデータを自分で取ってくるところからやろうとおもいます。どこからデータを取ってくるのかという点が重要になるわけですが、データ先としては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`,"./.馬身|.馬身|.

ウルトラマン ハヤタ 事故, 富士ステークス 過去 2020, 杉本昌隆 師匠, 朝ドラ 主題歌 歌詞, 長谷部誠 佐藤ありさ 結婚式, イノセンス ドラマ あらすじ, 巨人ファン ジャニーズ, エルコンドルパサー 凱旋門賞, Nhk 受信料 生活保護 返金, 最後から二番目の恋 再放送 2019, Nhk受信料 払えない シングルマザー, 野木亜紀子 名言, ミノンメン セット, コウノドリ 3 主題歌, 戦争映画 感想, 坂口涼太郎 歌, 石川県 社会人サッカー, サウジアラビア 原油, 阪神 歴代開幕投手, 1996 エリザベス女王杯, フレッド キリスト トランプ, 愛知県高校サッカー ツイッター, 清原翔 綾野剛 米津玄師, ライフスタイルカレッジ オープニング, テイエムオペラオー 繁殖, 長野博 ティガ なんj, 戦争ドラマ 2019, 千葉 クラブ チーム,

関連記事一覧