競馬サイトから結果情報をJSON形式で抜き取るJSコード(地方競馬サイト編)

2017年10月24日

Javascript テクノロジー プログラミング

プロスポーツの中でデータ活用が一番進んでいるのは「野球」だという話を聞きましたが、確かにテレビのスポーツニュースを聞いていても、選手情報に必ず数値情報を結びつけて表現していることが分かります。 数値分析をするという事は、それだけ分析することに意味があり、その分析数値を元にスポーツ自体も向上するし、見ている人のおもしろポイントなどもアップする事も理解できます。

スポーツにおける数値分析

近年オリンピックを含め、スポーツ競技を見ていると、テレビ画面に数字を表してくれていますが、自分の好きなスポーツ以外は、あまり意味が分からない数字もたくさんあります。 楽しむ意味で考えれば、自分がわかる数字だけ理解できれば十分だと思いますが、データサイエンティスト的な見方をすると、理解できない数字は、知らいない分析方法が存在するという現れかもしれません。 もちろん、個々のスポーツの競技内容を最近事情を知る必要もあるし、細かな競技のルールも熟知しなければならないので、やはり興味を持たないと中々しんどいかもしませんね。 競馬という数字競技もまた奥が深いのですが、意味が理解できると、面白味が増すので、そうなった時の数値の収集は非常に重要なミッションでもあります。

中央競馬と地方競馬

個人的に競馬を全く知らなかった僕としては、「中央競馬」と「地方競馬」の意味すら理解していませんでした。 関東地区で行われているのが「中央競馬」ではないかとぐらいしか考えていませんでしたが、中央競馬って全国の主要都市にある競馬で、地方競馬は、少し郊外にある競馬場で開催されているレースのようですね。 具体的には、JRA(中央競馬)サイト地方競馬サイトを見てもらえれば、各レース上が地名で書かれているので理解できると思います。 ちなみに、地方競馬には「南関東4競馬場」というジャンルもあり、何故こうした区分けがされているのか、未だに理解できていません・・・orz

地方競馬の結果情報

前回中央競馬のレース結果情報を抜き取るJSコードを掲載しましたが、調子に乗って地方競馬版も作ってみました。 競馬サイトから結果情報をJSON形式で抜き取るJSコード(JRAサイト編) 今回は以下のサイトから、情報を抜き出してみたいと思います。 南関東4競馬場公式WEBサイト 下記の遷移で、特定の競馬場での1日分の結果情報を取得できます。 TOP > レース結果 > 払戻金一覧 > 競馬場を選択 前回のJRAとはDOM構造も見栄えも違うのですが、前回と同じように、クロールに適した構造にはなっていないようです。

JSコード

(function(){ var $$ = function(){ $$.prototype.page2result(); }; // [console-tool] 競馬結果サイトからデータを引き抜き、JSON形式でprintする $$.prototype.page2result = function(){ var data = []; // var header = document.querySelector(".bangumi-header"); var main = $$.prototype.getMainData(document.querySelector("#bangumi-header")); // extra date var a = document.querySelectorAll("#contents a[name^='#']"); for(var i=0; i<a.length; i++){ // get-date var d2 = $$.prototype.getRaceData(a[i]); if(d2 !== null){ data.push(d2); } } var full = {"main":main , "data":data}; console.log(JSON.stringify(full,null," ")); }; // レース見出し取得 $$.prototype.getMainData = function(elm){ var main = {}; var dt = elm.querySelector("span.tx-normal"); var ptn = new RegExp("(.+)年(.+)月(.+)日"); if(dt.innerText.match(ptn)){ main.y = RegExp.$1; // 年 main.m = RegExp.$2; // 月 main.d = RegExp.$3; // 日 } var str = elm.querySelector(".mT5"); var ptn = new RegExp("第([0-9]+)回 (.+)競馬 第([0-9]+)日 "); if(str.innerText.match(ptn)){ main.r = RegExp.$1; // 回 main.p = RegExp.$2; // 場所 main.a = RegExp.$3; // 日 } return main; }; // レース結果情報の取得 $$.prototype.getRaceData = function(elm){ var data = null; if(!elm){return null;} var elm_raceNo = elm.nextElementSibling.querySelector("img"); var data = {}; data.raceNo = elm_raceNo.getAttribute("alt").replace("R",""); var elm1 = elm.nextElementSibling; var elm2 = elm1.nextElementSibling; var data1 = $$.prototype.getRaceResult_uma(elm2); var data2 = $$.prototype.getRaceResult_uma(elm2.nextElementSibling); data.uma = data1.concat(data2); return data; }; // $$.prototype.getRaceResult_uma = function(table){ var data = []; if(!table){return data;} var tr = table.getElementsByTagName("tr"); var th = tr[0].getElementsByTagName("th"); for(var i=0; i<th.length; i++){ var name = th[i].innerText; var cnt = i*3+1; var result = []; var price = []; for(var j=2; j<tr.length; j++){ var elm1 = tr[j].querySelector("td:nth-child("+(cnt+0)+")"); var elm2 = tr[j].querySelector("td:nth-child("+(cnt+1)+")"); if(!elm1 || !elm2){continue;} if(elm1.innerText !== "-" && elm2.innerText !== "-"){ result.push(elm1.innerText); price.push($$.prototype.txt2num(elm2.innerText)); } } if(result.join("")==="" && price.join("")===""){continue;} data.push({"name":name , "result":result.join("\n") , "price":price.join("\n")}); } return data; }; $$.prototype.web2num = function(txts){return txts; var arr = []; var sp = txts.split("\n"); for(var i=0; i<sp.length; i++){ arr.push($$.prototype.txt2num(sp[i])); } return arr.join("\n"); }; $$.prototype.txt2num = function(str){ var str1 = str; str1 = str1.split("円").join(""); str1 = str1.split(",").join(""); str1 = Number(str1); if(str1 === null){ return str; } else{ return str1; } }; new $$(); })(); これを前回同様、サイトのJSコードコンソールで実行すると、以下の結果が得られます。 { "main": { "y": "2017", "m": "10", "d": "20", "r": "6", "p": "浦和", "a": "5" }, "data": [ { "raceNo": "1", "uma": [ { "name": "単勝", "result": "7", "price": "140" }, { "name": "複勝", "result": "7\n8\n9", "price": "100\n210\n170" }, { "name": "枠複", "result": "7-8", "price": "260" }, { "name": "普通馬複", "result": "7-8", "price": "540" }, { "name": "枠単", "result": "7-8", "price": "190" }, { "name": "馬単", "result": "7-8", "price": "710" }, { "name": "ワイド", "result": "7-8\n7-9\n8-9", "price": "250\n230\n620" }, { "name": "三連複", "result": "7-8-9", "price": "930" }, { "name": "三連単", "result": "7-8-9", "price": "2720" } ] }, { "raceNo": "2", "uma": [ { "name": "単勝", "result": "3", "price": "360" }, { "name": "複勝", "result": "3\n2\n4", "price": "110\n110\n100" }, { "name": "枠複", "result": "2-3", "price": "600" }, { "name": "普通馬複", "result": "2-3", "price": "520" }, { "name": "枠単", "result": "3-2", "price": "1200" }, { "name": "馬単", "result": "3-2", "price": "1140" }, { "name": "ワイド", "result": "2-3\n3-4\n2-4", "price": "200\n170\n180" }, { "name": "三連複", "result": "2-3-4", "price": "400" }, { "name": "三連単", "result": "3-2-4", "price": "2990" } ] }, { "raceNo": "3", "uma": [ { "name": "単勝", "result": "4", "price": "570" }, { "name": "複勝", "result": "4\n10\n9", "price": "200\n130\n320" }, { "name": "枠複", "result": "4-8", "price": "400" }, { "name": "普通馬複", "result": "4-10", "price": "480" }, { "name": "枠単", "result": "4-8", "price": "670" }, { "name": "馬単", "result": "4-10", "price": "880" }, { "name": "ワイド", "result": "4-10\n4-9\n9-10", "price": "260\n760\n470" }, { "name": "三連複", "result": "4-9-10", "price": "840" }, { "name": "三連単", "result": "4-10-9", "price": "4310" } ] }, { "raceNo": "4", "uma": [ { "name": "単勝", "result": "3", "price": "340" }, { "name": "複勝", "result": "3\n4\n2", "price": "140\n120\n190" }, { "name": "普通馬複", "result": "3-4", "price": "360" }, { "name": "馬単", "result": "3-4", "price": "880" }, { "name": "ワイド", "result": "3-4\n2-3\n2-4", "price": "180\n310\n280" }, { "name": "三連複", "result": "2-3-4", "price": "390" }, { "name": "三連単", "result": "3-4-2", "price": "2570" } ] }, { "raceNo": "5", "uma": [ { "name": "単勝", "result": "4", "price": "340" }, { "name": "複勝", "result": "4\n2\n10", "price": "140\n170\n150" }, { "name": "枠複", "result": "2-4", "price": "710" }, { "name": "普通馬複", "result": "2-4", "price": "690" }, { "name": "枠単", "result": "4-2", "price": "1590" }, { "name": "馬単", "result": "4-2", "price": "1120" }, { "name": "ワイド", "result": "2-4\n4-10\n2-10", "price": "290\n300\n460" }, { "name": "三連複", "result": "2-4-10", "price": "1040" }, { "name": "三連単", "result": "4-2-10", "price": "4780" } ] }, { "raceNo": "6", "uma": [ { "name": "単勝", "result": "5", "price": "1200" }, { "name": "複勝", "result": "5\n7\n3", "price": "200\n140\n130" }, { "name": "枠複", "result": "5-7", "price": "1600" }, { "name": "普通馬複", "result": "5-7", "price": "1960" }, { "name": "枠単", "result": "5-7", "price": "3640" }, { "name": "馬単", "result": "5-7", "price": "3920" }, { "name": "ワイド", "result": "5-7\n3-5\n3-7", "price": "450\n370\n230" }, { "name": "三連複", "result": "3-5-7", "price": "920" }, { "name": "三連単", "result": "5-7-3", "price": "10350" } ] }, { "raceNo": "7", "uma": [ { "name": "単勝", "result": "2", "price": "7290" }, { "name": "複勝", "result": "2\n11\n4", "price": "620\n190\n110" }, { "name": "枠複", "result": "2-8", "price": "12850" }, { "name": "普通馬複", "result": "2-11", "price": "14690" }, { "name": "枠単", "result": "2-8", "price": "48030" }, { "name": "馬単", "result": "2-11", "price": "45370" }, { "name": "ワイド", "result": "2-11\n2-4\n4-11", "price": "3330\n1130\n250" }, { "name": "三連複", "result": "2-4-11", "price": "4680" }, { "name": "三連単", "result": "2-11-4", "price": "118520" } ] }, { "raceNo": "8", "uma": [ { "name": "単勝", "result": "5", "price": "700" }, { "name": "複勝", "result": "5\n8\n10", "price": "210\n120\n340" }, { "name": "枠複", "result": "5-7", "price": "670" }, { "name": "普通馬複", "result": "5-8", "price": "970" }, { "name": "枠単", "result": "5-7", "price": "2080" }, { "name": "馬単", "result": "5-8", "price": "3470" }, { "name": "ワイド", "result": "5-8\n5-10\n8-10", "price": "470\n1380\n1010" }, { "name": "三連複", "result": "5-8-10", "price": "4710" }, { "name": "三連単", "result": "5-8-10", "price": "24570" } ] }, { "raceNo": "9", "uma": [ { "name": "単勝", "result": "8", "price": "1230" }, { "name": "複勝", "result": "8\n11\n4", "price": "480\n850\n250" }, { "name": "枠複", "result": "6-8", "price": "6440" }, { "name": "普通馬複", "result": "8-11", "price": "23180" }, { "name": "枠単", "result": "6-8", "price": "18050" }, { "name": "馬単", "result": "8-11", "price": "36880" }, { "name": "ワイド", "result": "8-11\n4-8\n4-11", "price": "3670\n1670\n3120" }, { "name": "三連複", "result": "4-8-11", "price": "44590" }, { "name": "三連単", "result": "8-11-4", "price": "291600" } ] }, { "raceNo": "10", "uma": [ { "name": "単勝", "result": "9", "price": "940" }, { "name": "複勝", "result": "9\n6\n11", "price": "300\n170\n240" }, { "name": "枠複", "result": "6-7", "price": "670" }, { "name": "普通馬複", "result": "6-9", "price": "2450" }, { "name": "枠単", "result": "7-6", "price": "1420" }, { "name": "馬単", "result": "9-6", "price": "5330" }, { "name": "ワイド", "result": "6-9\n9-11\n6-11", "price": "920\n1120\n730" }, { "name": "三連複", "result": "6-9-11", "price": "5510" }, { "name": "三連単", "result": "9-6-11", "price": "37600" } ] }, { "raceNo": "11", "uma": [ { "name": "単勝", "result": "7", "price": "190" }, { "name": "複勝", "result": "7\n8\n1", "price": "100\n120\n170" }, { "name": "枠複", "result": "6-6", "price": "450" }, { "name": "普通馬複", "result": "7-8", "price": "470" }, { "name": "枠単", "result": "6-6", "price": "400" }, { "name": "馬単", "result": "7-8", "price": "620" }, { "name": "ワイド", "result": "7-8\n1-7\n1-8", "price": "240\n320\n490" }, { "name": "三連複", "result": "1-7-8", "price": "1020" }, { "name": "三連単", "result": "7-8-1", "price": "2760" } ] }, { "raceNo": "12", "uma": [ { "name": "単勝", "result": "6", "price": "2710" }, { "name": "複勝", "result": "6\n10\n8", "price": "340\n120\n1700" }, { "name": "枠複", "result": "5-7", "price": "720" }, { "name": "普通馬複", "result": "6-10", "price": "790" }, { "name": "枠単", "result": "5-7", "price": "3820" }, { "name": "馬単", "result": "6-10", "price": "4290" }, { "name": "ワイド", "result": "6-10\n6-8\n8-10", "price": "440\n11430\n1690" }, { "name": "三連複", "result": "6-8-10", "price": "7740" }, { "name": "三連単", "result": "6-10-8", "price": "68460" } ] } ] } このJSON形式も”{main:{} , data:{}}”と前回と同じスタイルにしています。 これで、レース結果をサクサク取得して、色々なレース情報と紐付けてみることで、分析を行うと、今まで気が付かなかったポイントなどに気がつくかもしれませんね。 あ、これ、金儲けでやってるわけではないですよ。あくまで仕事と数字学習の趣味です。 お金儲けできる方法があれば、こっそり教えてください。

人気の投稿

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。

ブログ アーカイブ