- Introduction
- Installation
- Arrays, Hashes or Structs
- Working with Navigators
- Data Access
- Chaining it all together
- Documentation
- Requirements
- Testing
- Contributing
The hoopscrape Ruby gem is a scraper for NBA data. It provides a number of ways to simplify data interaction, including :
- Structs - Intuitively access data via dot notation.
- Hashes - Pass data directly to ActiveRecord CRUD methods for easy database interaction.
- String arrays - Raw data for you to manipulate as you see fit.
Version 1.1
-
Fixed security vulnerabilities with Nokogiri and Rubocop. Unfortunately, this means HoopScrape now requires Ruby >= 2.1.0
-
Updated test suite.
-
Please report any issues you encounter!
In your application's Gemfile, include :
gem 'hoopscrape'
In your project dir, execute :
$ bundle install
$ gem install hoopscrape
If you intend to work with a single format, you can specify it at initialization. When working with multiple formats you should start with the default and convert as necessary using Array#to_structs or Array#to_hashes.
require 'hoopscrape'
hs = HoopScrape.new # String Arrays
hs_h = HoopScrape.new(format: :to_hashes) # Hash Arrays
hs_s = HoopScrape.new(format: :to_structs) # Struct Arrays
Arrays can easily be converted to Hashes or Structs
hs = HoopScrape.new
bs = es.boxscore(400828991) # Return an NbaBoxscore object
stats = bs.homePlayers # Returns a multidimensional array of Home Player stats
stats[4][2] # Player Name # => 'R. Hood'
stats[4][20] # Player Points # => '30'
s_hashes = stats.to_hashes # Returns array of Hashes
s_hashes[4][:name] # Player Name # => 'R. Hood'
s_hashes[4][:points] # Player Points # => '30'
s_structs = stats.to_structs # Returns array of Structs
s_structs[4].name # Player Name # => 'R. Hood'
s_structs[4].points # Player Points # => '30'
The Array#to_hashes and Array#to_structs methods can be passed an array of Symbols to use in place of the default field names.
team_list = HoopScrape.teamList
team_list_s = t.to_structs([:abbrev, :long_team_name, :div, :conf]) # New Field Names
team_list_s.last.long_team_name # => 'Utah Jazz'
Defaults are defined in the SymbolDefaults module. You can overwrite them or use them as templates, replacing individual symbols using the Array#change_sym! method.
Safe method
my_names = S_ROSTER.dup.change_sym!(:p_name, :full_name).change_sym!(:salary, :crazy_money)
players = HoopScrape.roster('CLE').players.to_structs(my_names)
players[3].full_name # => 'LeBron James'
players[3].crazy_money # => '22970500'
Note: Changes affect all instances of hoopscrape
S_TEAM # => [:team, :name, :division, :conference]
S_TEAM.replace [:short, :long, :div, :conf]
t = HoopScrape.teamList.to_structs
t.first.short # => 'BOS'
t.first.long # => 'Boston Celtics'
Table data is wrapped in a Navigator class which provides helper methods for moving through the table. The type of object the Navigator returns matches the format provided at hoopscrape instantiation.
Note: Data converted using Array#to_structs or Array#to_hashes is not wrapped in a Navigator.
# <Navigator> A Navigator for Home Player Stats Table
navigator = HoopScrape.boxscore(400878158).homePlayers
navigator[] # Array<Object> Returns the underlying Array of the Navigator
navigator[5] # <Object> 6th row of data
navigator.size # <Fixnum> Number of table rows
navigator.first # <Object> Access the first data row
navigator.last # <Object> Access the last data row
navigator.next # <Object> Access the next data row (nil if there is no more data)
navigator.curr # <Object> Access the current data row (nil at initialization)
navigator.prev # <Object> Access the previous data row (nil if there is no more data)
hs = HoopScrape.new
team_list = es.teamList # multidimensional array of Team info
team_list.last # => ['UTA', 'Utah Jazz', 'Northwest', 'Western']
team_list.last[0] # => 'UTA'
team_list.last[1] # => 'Utah Jazz'
team_list.last[2] # => 'Northwest'
team_list.last[3] # => 'Western'
Boxscore #homePlayers, #awayPlayers return a Navigator
hs = HoopScrape.new(format: :to_structs)
bs = es.boxscore(400875892) # Return an NbaBoxscore object
bs.id # <String> Boxscore ID # => '400875892'
bs.gameDate # <String> Game DateTime # => '2016-05-07 00:00:00'
bs.homeName # <String> Full Team Name
bs.homeScore # <String> Team Score
bs.homeTotals # <Object> Access the cumulative team totals
bs.homePlayers # <Navigator> A Navigator for Home Player Stats Table
bs.awayName # <String> Full Team Name
bs.awayScore # <String> Team Score
bs.awayTotals # <Object> Access the cumulative team totals
bs.awayPlayers # <Navigator> A Navigator for Home Player Stats Table
wade = bs.homePlayers[4] # <Object> of data for Row 5
wade.team # <String> Team ID # => 'MIA'
wade.id # <String> Player ID # => '1987'
wade.name # <String> Short Name # => 'D. Wade'
wade.position # <String> Position # => 'SG'
wade.minutes # <String> Minutes # => '36'
wade.fgm # <String> Shots Made # => '13'
wade.fga # <String> Shots Attempted # => '25'
wade.tpm # <String> 3P Made # => '4'
wade.tpa # <String> 3P Attempted # => '6'
wade.ftm # <String> Freethrows Made # => '8'
wade.fta # <String> Freethrows Att. # => '8'
wade.oreb # <String> Offensive Reb. # => '1'
wade.dreb # <String> Defensive Reb. # => '7'
wade.rebounds # <String> Total Rebounds # => '8'
wade.assists # <String> Assists # => '4'
wade.steals # <String> Steals # => '0'
wade.blocks # <String> Blocks # => '0'
wade.tos # <String> Turnovers # => '4'
wade.fouls # <String> Personal Fouls # => '1'
wade.plusminus # <String> Plus/Minus # => '-8'
wade.points # <String> Points # => '38'
wade.starter # <String> Starter? # => 'true'
miami = bs.homeTotals # <Object> Access the team totals
miami.team
miami.fgm
miami.fga
miami.tpm
miami.tpa
miami.ftm
miami.fta
miami.oreb
miami.dreb
miami.rebounds
miami.assists
miami.steals
miami.blocks
miami.turnovers
miami.fouls
miami.points
Roster #players is a Navigator.
roster = es.roster('UTA')
r_hash = es.roster('UTA', format: :to_hashes) # Pre-format players data
players = roster.players # Returns multidimensional array of Roster info
coach = roster.coach # Coach Name # => 'Quinn Snyder'
# Roster as an array of objects
players = players.to_structs # Returns array of Structs
players[2].team # Team ID # => 'UTA'
players[2].jersey # Jersey Number # => '11'
players[2].name # Name # => 'Alec Burks'
players[2].id # ID # => '6429'
players[2].position # Position # => 'SG'
players[2].age # Age # => '24'
players[2].height_ft # Height (ft) # => '6'
players[2].height_in # Height (in) # => '6'
players[2].salary # Salary # => '9463484'
players[2].weight # Weight # => '214'
players[2].college # College # => 'Colorado'
players[2].salary # Salary # => '9463484'
player = es.player(2991473) # Returns an NbaPlayer object
player.name #=> "Anthony Bennett"
player.age #=> "23"
player.weight #=> "245"
player.college #=> "UNLV"
player.height_ft #=> "6"
player.height_in #=> "8"
Schedule #allGames, #pastGames, #futureGames return a Navigator
schedule = es.schedule('UTA') # Gets latest available year and season type data
schedule = es.schedule('LAC', format: :to_structs) # Pre-format data (:to_hashes / :to_structs)
schedule = es.schedule('SAS', year: 2005) # Gets historical data for season ending in 2005
schedule = es.schedule('POR', season: 1) # Get specific season type (1 Pre/ 2 Regular/3 Post)
schedule.nextGame # <Object> Next unplayed game info
schedule.lastGame # <Object> Previously completed game info
schedule.nextTeamId # <String> Team ID of next opponent # => 'OKC'
schedule.nextGameId # <Fixnum> Index of next unplayed game
schedule.pastGames[] # Completed Games : [Object]
schedule.futureGames[] # Upcoming Games : [Object]
past = schedule.pastGames # Completed Games : <Navigator>
future = schedule.futureGames # Upcoming Games : <Navigator>
past = schedule.pastGames # Completed Games : <Navigator>
game = past.next # <Object> Game info
game.team # Team ID
game.game_num # Game # in Season
game.date # Game Date
game.home # Home?
game.opponent # Opponent ID
game.win # Win?
game.team_score # Team Score
game.opp_score # Opponent Score
game.boxscore_id # Boxscore ID
game.wins # Team Win Count
game.losses # Team Loss Count
game.datetime # Game DateTime
game.season_type # Season Type
future = schedule.futureGames # Upcoming Games : <Navigator>
game = future.next # <Object> Game info
game.team # Team ID
game.game_num # Game # in Season
game.date # Game Date
game.home # Home?
game.opponent # Opponent ID
game.time # Game Time
game.win # Win?
game.tv # Game on TV?
game.opp_score # Opponent Score
game.datetime # Game DateTime
game.season_type # Season Type
preseason = es.schedule('BOS', season: 1) # Get Preseason schedule
regular = es.schedule('NYK', season: 2) # Get Regular schedule
playoffs = es.schedule('OKC', season: 3) # Get Playoff schedule
The year parameter should correspond to the year in which the season ended.
schedule = es.schedule('SAS', year: 2005) # Data for 2004-05 Season
# Get a Boxscore from a past game
HoopScrape.schedule('OKC', season: 2).allGames[42].boxscore(:to_structs).awayPlayers.first.name
# Get a Roster from a Team ID
HoopScrape.boxscore(400827977).homeTotals[0].roster(:to_hashes).players.first[:name]
'cle'.roster(:to_structs).players.next.position
# Get a Schedule from a Team ID
HoopScrape.teamList.last[0].schedule(:to_hashes).lastGame.boxscore
'gsw'.schedule(:to_structs).lastGame.boxscore
Available on RubyDoc.info or locally:
$ yard doc
$ yard server
- Ruby >= 1.9.3
- Nokogiri ~> 1.6
- Rake
- minitest
$ rake
Bug reports and pull requests are welcome on GitHub at https://github.com/meissadia/hoopscrape
© 2016 Meissa Dia