vegas_insider_scraper 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
- - ">="
|