-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscrape_odds.js
173 lines (139 loc) · 3.96 KB
/
scrape_odds.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/**********************************
* 各種モジュールの読み込み
**********************************/
var client = require('cheerio-httpcli');
var fs = require('fs');
var date = require('date-utils');
/**********************************
* メイン処理
**********************************/
// ファイルを読み込む
var loadFile = function () {
return new Promise(function (resolve, reject) {
// racelist.jsonをロード
var data = fs.readFileSync(__dirname + '/racelist.json', 'utf-8');
// JSON形式に変換
var json = JSON.parse(data);
resolve(json);
});
};
// レースを選択する
var selectUrl = function (map) {
return new Promise(function (resolve, reject) {
var json = [];
// 既に終了したレースのURLはスクレイピングリストに追加しないよう処理する
// 現在時刻を取得
var date = new Date();
var now_time = Number(date.toFormat('HH24MM'));
map['time'].forEach(function(elem, idx) {
var race_time = Number(elem.replace(':', ''));
// まだ終了していないレースのURLのみ追加
if(race_time >= now_time) {
json.push(map['url'][idx]);
}
});
resolve(json);
});
};
// スクレイピングする
var scrape = function(urls) {
return new Promise(function (resolve, reject) {
var race = {};
// URL一つ一つにアクセス
urls.forEach(function(elem) {
// URLから数字のみ抽出
var race_id = elem.replace(/[^0-9]/g,'');
// URLを作成
var url = 'https://www.nankankeiba.com/odds/' + race_id + '01.do';
// レースIDをきーにして要素を追加
race[race_id] = "";
// スクレイピング実行
var data = client.fetchSync(url);
// スクレイピングデータを格納
var $ = data.$;
// データを格納するリスト
var list = [];
// 各データを格納するJSON
var json;
// テーブルにアクセス
$('div.twoColEq_L td').each(function (idx) {
// td要素のテキスト
var text = $(this).text();
switch(idx % 5) {
// 枠番
case 0:
json = {};
// 数字のみ抽出して格納
json['wakuban'] = text.replace(/[^0-9]/g,'');
break;
// 馬番
case 1:
// 数字のみ抽出して格納
json['umaban'] = text.replace(/[^0-9]/g,'');
break;
// 単勝オッズ
case 3:
// 数字のみ抽出して格納
json['tan_odds'] = parseFloat(text.replace(/[^0-9^\.]/g,''));
break;
// 複勝オッズ
case 4:
// 数字のみ抽出してハイフンで分割
text = text.replace(/[^0-9^\.-]/g,'').split("-");
// 2で除算したものを格納
text = parseFloat(String(((Number(text[0]) + Number(text[1])) / 2).toFixed(1)));
json['fuku_odds'] = text;
// 全てのデータを格納し終わったら、JSONをリストに追加
list.push(json);
break;
default:
break;
} // switch
}); // each
// レースIDをキーにして格納
race[race_id] = list;
console.log(url);
// 全てのレースのスクレイピングが終了したら
if(Object.keys(race).length == urls.length) {
resolve(race);
}
}); // forEach
});
}
// ファイルに書き込む
var writeFile = function (data) {
return new Promise(function (resolve, reject) {
// データをJSON形式に変換
var text = JSON.stringify(data, null, ' ');
// ファイル保存
fs.writeFileSync(__dirname + '/odds.json', text);
resolve();
});
};
// メイン処理を実行する
var main = function () {
return new Promise(function (resolve, reject) {
Promise.resolve()
.then(function () {
return loadFile();
})
.then(function (results) {
return selectUrl(results);
})
.then(function (results) {
return scrape(results);
})
.then(function (results) {
return writeFile(results);
})
.then(function (results) {
// 完了
resolve();
})
.catch(function (err) {
// エラー通知
reject(err);
});
});
};
main();