hoopscrape is not associated with ESPN or the NBA
Table of Contents
Introduction
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!
Installation
Rails
In your application's Gemfile, include :
gem 'hoopscrape'
In your project dir, execute :
$ bundle install
Manual
$ gem install hoopscrape
Arrays, Hashes or Structs
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
hs_h = HoopScrape.new(format: :to_hashes)
hs_s = HoopScrape.new(format: :to_structs)
Working With Multiple Formats
Arrays can easily be converted to Hashes or Structs
Default format
hs = HoopScrape.new
bs = es.boxscore(400828991)
stats = bs.homePlayers
stats[4][2]
stats[4][20]
Same data using Hashes
s_hashes = stats.to_hashes
s_hashes[4][:name]
s_hashes[4][:points]
Same data using Structs
s_structs = stats.to_structs
s_structs[4].name
s_structs[4].points
Customize Field Names for Hash and Struct Conversion
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])
team_list_s.last.long_team_name
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.
Default As Template
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
players[3].crazy_money
Overwrite Default
Note: Changes affect all instances of hoopscrape
S_TEAM
S_TEAM.replace [:short, :long, :div, :conf]
t = HoopScrape.teamList.to_structs
t.first.short
t.first.long
Working with Navigators
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 Methods
navigator = HoopScrape.boxscore(400878158).homePlayers
navigator[]
navigator[5]
navigator.size
navigator.first
navigator.last
navigator.next
navigator.curr
navigator.prev
Data Access
NBA Team List
hs = HoopScrape.new
team_list = es.teamList
team_list.last
team_list.last[0]
team_list.last[1]
team_list.last[2]
team_list.last[3]
Boxscore
Boxscore #homePlayers, #awayPlayers return a Navigator
hs = HoopScrape.new(format: :to_structs)
bs = es.boxscore(400875892)
bs.id
bs.gameDate
bs.homeName
bs.homeScore
bs.homeTotals
bs.homePlayers
bs.awayName
bs.awayScore
bs.awayTotals
bs.awayPlayers
Player Data
wade = bs.homePlayers[4]
wade.team
wade.id
wade.name
wade.position
wade.minutes
wade.fgm
wade.fga
wade.tpm
wade.tpa
wade.ftm
wade.fta
wade.oreb
wade.dreb
wade.rebounds
wade.assists
wade.steals
wade.blocks
wade.tos
wade.fouls
wade.plusminus
wade.points
wade.starter
Team Data
miami = bs.homeTotals
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
Roster #players is a Navigator.
roster = es.roster('UTA')
r_hash = es.roster('UTA', format: :to_hashes)
players = roster.players
coach = roster.coach
players = players.to_structs
players[2].team
players[2].jersey
players[2].name
players[2].id
players[2].position
players[2].age
players[2].height_ft
players[2].height_in
players[2].salary
players[2].weight
players[2].college
players[2].salary
Player
player = es.player(2991473)
player.name
player.age
player.weight
player.college
player.height_ft
player.height_in
Schedule
Schedule #allGames, #pastGames, #futureGames return a Navigator
schedule = es.schedule('UTA')
schedule = es.schedule('LAC', format: :to_structs)
schedule = es.schedule('SAS', year: 2005)
schedule = es.schedule('POR', season: 1)
schedule.nextGame
schedule.lastGame
schedule.nextTeamId
schedule.nextGameId
schedule.pastGames[]
schedule.futureGames[]
past = schedule.pastGames
future = schedule.futureGames
Past Schedule Games as Structs
past = schedule.pastGames
game = past.next
game.team
game.game_num
game.date
game.home
game.opponent
game.win
game.team_score
game.opp_score
game.boxscore_id
game.wins
game.losses
game.datetime
game.season_type
Future Schedule Games as Structs
future = schedule.futureGames
game = future.next
game.team
game.game_num
game.date
game.home
game.opponent
game.time
game.win
game.tv
game.opp_score
game.datetime
game.season_type
Select a specific Season Type
preseason = es.schedule('BOS', season: 1)
regular = es.schedule('NYK', season: 2)
playoffs = es.schedule('OKC', season: 3)
Select Historic Schedule data
The year parameter should correspond to the year in which the season ended.
schedule = es.schedule('SAS', year: 2005)
Chaining it all together
HoopScrape.schedule('OKC', season: 2).allGames[42].boxscore(:to_structs).awayPlayers.first.name
HoopScrape.boxscore(400827977).homeTotals[0].roster(:to_hashes).players.first[:name]
'cle'.roster(:to_structs).players.next.position
HoopScrape.teamList.last[0].schedule(:to_hashes).lastGame.boxscore
'gsw'.schedule(:to_structs).lastGame.boxscore
Documentation
Available on RubyDoc.info or locally:
$ yard doc
$ yard server
Requirements
Ruby version
Dependencies
- Nokogiri ~> 1.6
- Rake
- minitest
Testing
$ rake
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/meissadia/hoopscrape
© 2016 Meissa Dia