vegas_insider_scraper 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/sports/mlb.rb +4 -7
- data/lib/sports/nhl.rb +4 -7
- data/lib/sports/scraper_league.rb +96 -43
- data/lib/vegas_insider_scraper.rb +1 -0
- metadata +10 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a02df40a50546346abca93962a41e2db68b124b
|
4
|
+
data.tar.gz: 9f5e27501aa14da7de8a49f840c4be1d85a8e21d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 69cf0956935f1f629da5a9a65211fb9c3996bf22b80d0d17d7bd423d170b2cd5c9d52815e5b9588783780a80cd9aaad8ccd65ee7ebf9217c0752699dd7a7057b
|
7
|
+
data.tar.gz: fe645dd5111a22ff77837e1c588c0b20805b59b1a2a5a54ec61368faa4d72e15f4cc4d354a9a7bf2f6a27f30ba4316f959b329f74a3f95f37465901124b7b1e7
|
data/lib/sports/mlb.rb
CHANGED
@@ -4,16 +4,13 @@ class MLB < ScraperLeague
|
|
4
4
|
def initialize
|
5
5
|
@sport_id = 4
|
6
6
|
@sport_name = :mlb
|
7
|
-
@moneyline_sport = true
|
8
7
|
super
|
8
|
+
@moneyline_sport = true
|
9
9
|
end
|
10
10
|
|
11
|
-
def
|
12
|
-
|
13
|
-
|
14
|
-
get_lines(url, sport_id)
|
15
|
-
end
|
16
|
-
return true
|
11
|
+
def current_games
|
12
|
+
@current_games ||= get_lines(["http://www.vegasinsider.com/#{sport_name}/odds/las-vegas/run/",
|
13
|
+
"http://www.vegasinsider.com/#{sport_name}/odds/las-vegas/"])
|
17
14
|
end
|
18
15
|
|
19
16
|
end
|
data/lib/sports/nhl.rb
CHANGED
@@ -4,15 +4,12 @@ class NHL < ScraperLeague
|
|
4
4
|
def initialize
|
5
5
|
@sport_id = 5
|
6
6
|
@sport_name = :nhl
|
7
|
-
@moneyline_sport = false
|
8
7
|
super
|
8
|
+
@moneyline_sport = true
|
9
9
|
end
|
10
10
|
|
11
|
-
def
|
12
|
-
|
13
|
-
|
14
|
-
get_lines(url, sport_id)
|
15
|
-
Game.save_games(games)
|
16
|
-
end
|
11
|
+
def current_games
|
12
|
+
@current_games ||= get_lines(["http://www.vegasinsider.com/#{sport_name}/odds/las-vegas/puck/",
|
13
|
+
"http://www.vegasinsider.com/#{sport_name}/odds/las-vegas/"])
|
17
14
|
end
|
18
15
|
end
|
@@ -18,7 +18,7 @@ class ScraperLeague
|
|
18
18
|
|
19
19
|
# Gets the upcoming/current games for the sport
|
20
20
|
def current_games
|
21
|
-
@current_games ||= get_lines("http://www.vegasinsider.com/#{sport_name}/odds/las-vegas/")
|
21
|
+
@current_games ||= get_lines(["http://www.vegasinsider.com/#{sport_name}/odds/las-vegas/","http://www.vegasinsider.com/#{sport_name}/odds/las-vegas/money/"])
|
22
22
|
end
|
23
23
|
|
24
24
|
# Gets all of the schedule and results for each team
|
@@ -239,29 +239,33 @@ class ScraperLeague
|
|
239
239
|
|
240
240
|
##########################################
|
241
241
|
# Gets the current lines for a given sport
|
242
|
-
def get_lines(
|
242
|
+
def get_lines(urls)
|
243
243
|
games = []
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
game.
|
253
|
-
game.
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
last_game
|
244
|
+
|
245
|
+
urls.each { |url|
|
246
|
+
is_first_url = games.empty?
|
247
|
+
doc = Nokogiri::HTML(open(url))
|
248
|
+
doc.css('.viBodyBorderNorm .frodds-data-tbl tr').each do |game_row|
|
249
|
+
|
250
|
+
game_cell = game_row.at_css('td:first-child')
|
251
|
+
teams = game_cell_parser(game_cell)
|
252
|
+
game = Game.new(home_team: teams[1], away_team: teams[0])
|
253
|
+
if game.teams_found?
|
254
|
+
game.update(time: get_game_time(game_cell))
|
255
|
+
is_first_url ? (games.push game) : (game = game.find_equal(games))
|
256
|
+
game.update(vegas_info: get_line(get_odds(game_row)))
|
257
|
+
game.update(vegas_info: get_line(get_odds_inner_html(game_row)))
|
258
|
+
|
259
|
+
else
|
260
|
+
last_game = games.last
|
261
|
+
if last_game
|
262
|
+
last_game.update(notes: game_cell.content)
|
263
|
+
last_game.update(doubleheader: doubleheader_id(game_cell.content))
|
264
|
+
end
|
261
265
|
end
|
262
266
|
end
|
263
|
-
|
264
|
-
games
|
267
|
+
}
|
268
|
+
games
|
265
269
|
end
|
266
270
|
|
267
271
|
# Utility method for scraping current lines
|
@@ -285,26 +289,37 @@ class ScraperLeague
|
|
285
289
|
# Utility method for scraping current lines
|
286
290
|
# * getting odds from the cell, removing whitespace, and converting 1/2 to 0.5
|
287
291
|
def get_odds(odds_element)
|
288
|
-
(odds_element.at_css('td:nth-child(3) a')
|
292
|
+
(odds_element.at_css('td:nth-child(3) a')&.content || '').gsub(" ","").gsub("½",".5").strip
|
293
|
+
end
|
294
|
+
def get_odds_inner_html(odds_element)
|
295
|
+
((odds_element.at_css('td:nth-child(3) a'))&.inner_html || '').encode('utf-8').gsub(" ","").gsub("½",".5").strip
|
289
296
|
end
|
290
297
|
|
291
298
|
# Utility method for scraping current lines
|
292
299
|
# * parsing the lines for non-moneyline sports
|
293
|
-
def
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
300
|
+
def get_line(odds_string)
|
301
|
+
odds = matchdata_to_hash(RegularExpressions::ODDS.match(odds_string)) || {}
|
302
|
+
runlines_odds = matchdata_to_hash(RegularExpressions::RUNLINE_ODDS.match(odds_string)) || {}
|
303
|
+
moneyline_odds = matchdata_to_hash(RegularExpressions::MONEYLINE_ODDS.match(odds_string)) || {}
|
304
|
+
|
305
|
+
result = odds.merge(runlines_odds).merge(moneyline_odds)
|
306
|
+
result.each { |k,v| result[k] = result[k].to_s.to_f if result[k] }
|
307
|
+
get_home_and_away(result)
|
308
|
+
|
309
|
+
end
|
310
|
+
|
311
|
+
# Utility method for scraping current lines
|
312
|
+
# * filling the home/away lines
|
313
|
+
def get_home_and_away(result)
|
314
|
+
result['away_line'] = -result['home_line'] if result['home_line']
|
315
|
+
result['home_line'] = -result['away_line'] if result['away_line']
|
316
|
+
result
|
302
317
|
end
|
303
318
|
|
304
319
|
# Utility method for scraping current lines
|
305
320
|
# * parsing the odds to get a number
|
306
321
|
def odds_reader(odds)
|
307
|
-
case odds when '' then nil when 'PK' then 0 else odds.to_f end
|
322
|
+
case odds&.strip when '',nil then nil when 'PK' then 0 else odds.to_f end
|
308
323
|
end
|
309
324
|
|
310
325
|
# Utility method for scraping current lines
|
@@ -337,12 +352,16 @@ class ScraperLeague
|
|
337
352
|
if game_finished?(row)
|
338
353
|
case m
|
339
354
|
when 2
|
340
|
-
|
341
|
-
|
342
|
-
|
355
|
+
formatted = odds_reader(remove_element_whitespace(cell))
|
356
|
+
home_team = (game.home_or_away_team(team) == :home)
|
357
|
+
if moneyline_sport
|
358
|
+
home_team ? game.update(vegas_info: {home_moneyline: formatted}) : game.update(vegas_info: {away_moneyline: formatted})
|
359
|
+
else
|
360
|
+
home_line = (formatted && !home_team) ? -formatted : formatted
|
361
|
+
game.update(vegas_info: {home_line: home_line, away_line: (home_line ? -home_line : nil)})
|
343
362
|
end
|
344
363
|
|
345
|
-
when 3 then game.update(over_under: remove_element_whitespace(cell))
|
364
|
+
when 3 then game.update(vegas_info: { over_under: remove_element_whitespace(cell)})
|
346
365
|
when 4 then game.update(game_results(cell, team, opponent))
|
347
366
|
when 5 then game.update(ats_results(cell, team, opponent))
|
348
367
|
end
|
@@ -350,7 +369,7 @@ class ScraperLeague
|
|
350
369
|
end
|
351
370
|
game
|
352
371
|
end
|
353
|
-
{ team: team, games: games.compact.map{ |game| game
|
372
|
+
{ team: team, games: games.compact.map{ |game| game } }
|
354
373
|
end
|
355
374
|
|
356
375
|
# Utility method for scraping team page results
|
@@ -431,7 +450,7 @@ class ScraperLeague
|
|
431
450
|
end
|
432
451
|
|
433
452
|
def matchdata_to_hash(matchdata)
|
434
|
-
matchdata ? Hash[*matchdata.names.map{ |name| [name,
|
453
|
+
matchdata ? Hash[*matchdata.names.map{ |name| [name,(matchdata[name] ? matchdata[name].downcase.to_sym : nil)] }.flatten].compact : {}
|
435
454
|
end
|
436
455
|
|
437
456
|
# Regular Expressions Module
|
@@ -442,8 +461,12 @@ class ScraperLeague
|
|
442
461
|
|
443
462
|
TIME_REGEX = /(?<mo>\d{2})\/(?<d>\d{2}) (?<h>\d+):(?<mi>\d{2}) (?<mer>\w{2})/
|
444
463
|
MONEYLINE_OVER_UNDER = /(?<ou>\d+(\.5)?)[ou]/x
|
445
|
-
|
446
|
-
|
464
|
+
|
465
|
+
ODDS = /(<br><br>(?<home_line>-\d+(\.5)?))|(<br>(?<away_line>-\d+(\.5)?)[+-]\d\d<br>)|
|
466
|
+
((?<over_under>\d+(\.5)?)[ou]-\d{2}(?<home_line>-\d+(.5)?)-\d\d\z)|
|
467
|
+
((?<away_line>-\d+(.5)?)-\d\d(?<over_under>\d+(\.5)?)[ou]-\d{2}\z)/x
|
468
|
+
RUNLINE_ODDS = /(?<away_line>(\+|-)\d+(\.5)?)\/(\+|-)\d{3}(?<home_line>(\+|-)\d+(\.5)?)\/(\+|-)\d{3}/
|
469
|
+
MONEYLINE_ODDS = /((?<over_under>\d+(\.5)?)[ou]-\d{2})?(?<away_moneyline>(\+|-)\d{3}\d*)(?<home_moneyline>(\+|-)\d{3}\d*)/
|
447
470
|
|
448
471
|
DOUBLEHEADER = /DH Gm (?<id>\d)/
|
449
472
|
RESULTS_DOUBLEHEADER = /\(DH (?<doubleheader>\d)\)/
|
@@ -453,7 +476,7 @@ class ScraperLeague
|
|
453
476
|
end
|
454
477
|
|
455
478
|
class Game
|
456
|
-
attr_reader :time, :
|
479
|
+
attr_reader :time, :away_team, :home_team, :vegas_info,
|
457
480
|
:ending, :winning_team, :winning_score, :losing_score, :ats_winner, :over_under_result, :doubleheader, :notes
|
458
481
|
|
459
482
|
def initialize(args = {})
|
@@ -461,7 +484,10 @@ class ScraperLeague
|
|
461
484
|
end
|
462
485
|
|
463
486
|
def update(args = {})
|
464
|
-
Game.sanitize(args).map { |attribute, value|
|
487
|
+
Game.sanitize(args).map { |attribute, value|
|
488
|
+
new_val = (attribute == :vegas_info && value && vegas_info) ? value.merge(vegas_info) : value
|
489
|
+
instance_variable_set("@#{attribute}", new_val)
|
490
|
+
}
|
465
491
|
return self
|
466
492
|
end
|
467
493
|
|
@@ -469,16 +495,43 @@ class ScraperLeague
|
|
469
495
|
home_team && away_team
|
470
496
|
end
|
471
497
|
|
498
|
+
def find_equal(games)
|
499
|
+
games.each { |game| return game if game == self }
|
500
|
+
end
|
501
|
+
|
502
|
+
def ==(other_game)
|
503
|
+
home_team == other_game.home_team && away_team == other_game.away_team && time.to_date == other_game.time.to_date && doubleheader == other_game.doubleheader
|
504
|
+
end
|
505
|
+
|
506
|
+
def home_or_away_team(team)
|
507
|
+
case team
|
508
|
+
when home_team then :home
|
509
|
+
when away_team then :away
|
510
|
+
else nil end
|
511
|
+
end
|
512
|
+
|
472
513
|
def as_json
|
473
514
|
instance_variables.each_with_object({}) { |var, hash| hash[var.to_s.delete("@").to_sym] = instance_variable_get(var) }
|
474
515
|
end
|
475
516
|
|
476
517
|
private
|
477
518
|
def self.sanitize(args)
|
478
|
-
permitted_keys = [:time, :
|
519
|
+
permitted_keys = [:time, :away_team, :home_team, :vegas_info,
|
479
520
|
:ending, :winning_team, :winning_score, :losing_score, :ats_winner, :over_under_result, :doubleheader, :notes]
|
480
521
|
args.select { |key,_| permitted_keys.include? key }
|
481
522
|
end
|
482
523
|
end
|
483
524
|
|
525
|
+
end
|
526
|
+
|
527
|
+
class Array
|
528
|
+
def as_json
|
529
|
+
map { |v| v.as_json }
|
530
|
+
end
|
531
|
+
end
|
532
|
+
|
533
|
+
class Hash
|
534
|
+
def compact
|
535
|
+
self.select { |_, value| !value.nil? }
|
536
|
+
end
|
484
537
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vegas_insider_scraper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew Reitz
|
@@ -14,16 +14,22 @@ dependencies:
|
|
14
14
|
name: nokogiri
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
17
20
|
- - ">="
|
18
21
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
22
|
+
version: 1.6.8
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.6'
|
24
30
|
- - ">="
|
25
31
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
32
|
+
version: 1.6.8
|
27
33
|
description: A gem to scrape the web for sports statistics, teams, betting lines,
|
28
34
|
records, and results!
|
29
35
|
email: reitz1994@gmail.com
|
@@ -51,7 +57,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
51
57
|
requirements:
|
52
58
|
- - ">="
|
53
59
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
60
|
+
version: 2.3.1
|
55
61
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
62
|
requirements:
|
57
63
|
- - ">="
|