Basketball Reference Scraper avatar

Basketball Reference Scraper

Pricing

from $10.00 / 1,000 results

Go to Apify Store
Basketball Reference Scraper

Basketball Reference Scraper

Get NBA/ABA data from Basketball-Reference: full career stats by player name, a season's full leaderboard by stat type, team rosters, draft classes with career totals, and MVP/ROY/DPOY/All-NBA voting for any season back to 1950. No login, no API key needed.

Pricing

from $10.00 / 1,000 results

Rating

0.0

(0)

Developer

Norm Data

Norm Data

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

Norm Data

Basketball Reference Scraper

Get NBA/ABA data from Basketball-Reference.com with no login: full career stats by player name, a whole season's leaderboard by stat type, a team's roster and stats, a draft class with career totals, or MVP/ROY/DPOY/All-NBA voting for any season back to 1950.

Here is one real row (player mode, one season of a career):

{
"player_id": "jamesle01",
"name": "LeBron James",
"player_url": "https://www.basketball-reference.com/players/j/jamesle01.html",
"position": "Small Forward, Power Forward, Point Guard, Center, and Shooting Guard",
"shoots": "Right",
"height": "6-9",
"weight_lb": 250,
"birth_date": "December 30, 1984",
"birth_place": "Akron, Ohio",
"high_school": "St. Vincent-St. Mary in Akron, Ohio",
"draft": "Cleveland Cavaliers, 1st round (1st pick, 1st overall), 2003 NBA Draft",
"career_per_game": [
{ "season": "2003-04", "team": "CLE", "games": 79, "points_per_game": 20.9, "assists_per_game": 5.9 }
],
"career_advanced": [{ "season": "2003-04", "per": 18.3, "win_shares": 5.1, "value_over_replacement": 2.9 }],
"scraped_at": "2026-09-12T00:00:00.000Z"
}

What it does

Reads Basketball-Reference.com's own public pages directly and normalizes every table into clean, flat rows.

  • Player resolves a name (via Basketball-Reference's own search) or a direct ID to full career stats: bio, per-game/totals/advanced by season, and playoffs.
  • Season returns a whole year's leaderboard for one stat type (per game, totals, advanced, per 36 minutes, or per 100 possessions), with server-side-equivalent filters for team, minimum games, and minimum minutes per game.
  • Team returns one team-season's roster joined with that season's per-game stats.
  • Draft returns a full draft class with career totals and advanced metrics through the present.
  • Awards returns MVP/ROY/DPOY/SMOY/MIP/Clutch POY/All-NBA/All-Defense/All-Rookie/Coach of the Year voting for one season, including real vote share.

Missing source values are returned as null, never invented.

Why this scraper

  • Every mode both real competitors split across two separate Actors, plus three neither has. One competitor does player career stats; the other does season leaderboards. Neither has team rosters, draft classes, or awards voting - this Actor covers all five in one place.
  • Real bugs caught before shipping, not left in. Basketball-Reference appends a non-player "League Average" summary row to every season leaderboard - excluded here, confirmed live rather than assumed. A raw field code (g) genuinely means different things on different tables (career games on a draft page, that season's team games on a Coach of the Year row) - handled correctly on each, not treated as one universal rename.
  • Handles Basketball-Reference's own anti-scrape layout. A real, confirmed subset of its stat tables are wrapped in HTML comments (which tables varies by page) - unwrapped generically here, not hardcoded to one page's specific table list.
  • No API key, no login, no browser. Reads only what a normal visitor's page load reads.

How it compares

Checked directly against both real Basketball-Reference scrapers on Apify (their own declared input/output, not a guess):

CapabilityThis actorlulzasaur/basketball-reference-scraperparseforge/basketball-reference-scraper
Player career stats (per-game, totals, advanced, playoffs)yesyesno
Season leaderboard (all players, one stat type)yesnoyes
Team rostersyesnono
Draft classesyesnono
Awards voting (MVP/ROY/DPOY/All-NBA/etc.)yesnono
Season leaderboard filters (team, min games, min minutes)yesn/ano
maxItems capyesnot documentedyes
Declared Apify dataset schemayesnot documentednot documented

Use cases

  • Fantasy basketball. Per-game averages and season leaderboards to build rankings.
  • Historical analysis. Compare eras with career per-game, totals, and advanced stats.
  • Draft research. A draft class's real career output, ranked by pick.
  • Awards/HOF projection. Real MVP/DPOY/All-NBA voting share, not just who won.
  • Team-building and roster analysis. A team-season's full roster with real production per player.
  • Sports journalism and content. Structured stats ready for a chart, table, or story.

Quickstart

Player career stats by name:

{ "mode": "player", "playerNames": ["LeBron James", "Nikola Jokić"] }

Season leaderboard: Boston players in 2023-24, 20+ games and 15+ minutes per game.

{ "mode": "season", "year": 2024, "statType": "per_game", "team": "BOS", "minGames": 20, "minMinutesPerGame": 15 }

A team's full roster and stats:

{ "mode": "team", "teamCode": "BOS", "teamYear": 2024 }

A draft class:

{ "mode": "draft", "draftYear": 2020 }

A season's awards voting:

{ "mode": "awards", "awardsYear": 2024 }

Input reference

FieldApplies toDescription
maxItemsallCeiling on rows written.
modeallplayer, season, team, draft, or awards.
playerNames / playerIdsplayerNames (resolved via Basketball-Reference's own search) or direct player codes.
year / statTypeseasonSeason end year (e.g. 2024 for 2023-24) and per_game/totals/advanced/per_minute/per_poss.
team / minGames / minMinutesPerGameseasonOptional filters on the leaderboard.
teamCode / teamYearteam3-letter team code and season end year.
draftYeardraftThe draft class's year.
awardsYearawardsThe season's end year.

Output reference (selected)

FieldDescription
player_id / name / player_urlIdentity (player mode).
position / shoots / height / weight_lb / birth_date / birth_place / college / high_school / draftBio (player mode).
career_per_game / career_totals / career_advanced / playoffs_per_gameOne entry per season (player mode).
player_id / player_name / team / stat fieldsSeason, team, and draft mode rows.
category / rank / coach_name / votes_first / points_won / points_max / award_shareAwards mode.
all_nba_team / all_defense_team / all_rookie_team / first_team_votes / second_team_votes / third_team_votesAwards mode: All-NBA/All-Defense/All-Rookie team voting only.
per / win_shares / box_plus_minus / value_over_replacementAdvanced metrics (PER, WS, BPM, VORP - Basketball-Reference's own terms).
query / errorSet on an unresolved player lookup.
scraped_atISO 8601 collection timestamp.

Run via API and CLI

curl -X POST "https://api.apify.com/v2/acts/USERNAME~basketball-reference-scraper/run-sync-get-dataset-items?token=<TOKEN>" \
-H "Content-Type: application/json" \
-d '{"mode":"player","playerNames":["LeBron James"]}'
$apify call USERNAME/basketball-reference-scraper --input '{"mode":"season","year":2024,"statType":"per_game"}'

Fetch results

curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=json"
curl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=csv"

Billing and limits

  • Pay per result. Billed per row written (one row per player in player mode; one row per player/pick/award-line in season/team/draft/awards mode).
  • No charge on failure. A run that produces zero rows fails with a message and is not billed.
  • An unresolved player name/ID still writes one error: "not found" row and is billed as a base row.
  • Free Apify plans run the built-in 10-row sample only.

FAQ and troubleshooting

Do I need an API key? No. Basketball-Reference's own public pages are read directly, with no key and no login.

Why did my player search return "not found"? The name didn't match anything in Basketball-Reference's own search. Try a more complete name, or use playerIds with the exact code from the player's URL (e.g. jamesle01).

Why does a season leaderboard have more rows than real players? A player traded mid-season gets one row per team plus a "TOT" (total) row - this is Basketball-Reference's own real convention, not a duplicate. Basketball-Reference's own trailing "League Average" summary row is excluded (it isn't a player).

Why is career_games sometimes labeled games instead? In draft mode, that field really is a career total. In awards mode's Coach of the Year rows, the identical raw source field means that season's team games - kept as games there rather than mislabeled as a career total.

What are PER, WS, BPM, and VORP? Basketball-Reference's own advanced metrics: Player Efficiency Rating, Win Shares, Box Plus/Minus, and Value Over Replacement Player. Passed through under their real, industry-standard names, not invented abbreviations.

How current is the data? Read live from Basketball-Reference.com on every run. It is not cached.

Is this an official NBA/Basketball-Reference tool? No. Independent, not affiliated with either. It reads only publicly available pages.

Local development

bun install
bun test # offline: table parsing, field mapping, bio parsing (real fixtures)
bun run src/main.ts # reads storage/key_value_stores/default/INPUT.json