Basketball Reference Scraper
Pricing
from $10.00 / 1,000 results
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
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share

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):
| Capability | This actor | lulzasaur/basketball-reference-scraper | parseforge/basketball-reference-scraper |
|---|---|---|---|
| Player career stats (per-game, totals, advanced, playoffs) | yes | yes | no |
| Season leaderboard (all players, one stat type) | yes | no | yes |
| Team rosters | yes | no | no |
| Draft classes | yes | no | no |
| Awards voting (MVP/ROY/DPOY/All-NBA/etc.) | yes | no | no |
| Season leaderboard filters (team, min games, min minutes) | yes | n/a | no |
maxItems cap | yes | not documented | yes |
| Declared Apify dataset schema | yes | not documented | not 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
| Field | Applies to | Description |
|---|---|---|
maxItems | all | Ceiling on rows written. |
mode | all | player, season, team, draft, or awards. |
playerNames / playerIds | player | Names (resolved via Basketball-Reference's own search) or direct player codes. |
year / statType | season | Season end year (e.g. 2024 for 2023-24) and per_game/totals/advanced/per_minute/per_poss. |
team / minGames / minMinutesPerGame | season | Optional filters on the leaderboard. |
teamCode / teamYear | team | 3-letter team code and season end year. |
draftYear | draft | The draft class's year. |
awardsYear | awards | The season's end year. |
Output reference (selected)
| Field | Description |
|---|---|
player_id / name / player_url | Identity (player mode). |
position / shoots / height / weight_lb / birth_date / birth_place / college / high_school / draft | Bio (player mode). |
career_per_game / career_totals / career_advanced / playoffs_per_game | One entry per season (player mode). |
player_id / player_name / team / stat fields | Season, team, and draft mode rows. |
category / rank / coach_name / votes_first / points_won / points_max / award_share | Awards mode. |
all_nba_team / all_defense_team / all_rookie_team / first_team_votes / second_team_votes / third_team_votes | Awards mode: All-NBA/All-Defense/All-Rookie team voting only. |
per / win_shares / box_plus_minus / value_over_replacement | Advanced metrics (PER, WS, BPM, VORP - Basketball-Reference's own terms). |
query / error | Set on an unresolved player lookup. |
scraped_at | ISO 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 installbun test # offline: table parsing, field mapping, bio parsing (real fixtures)bun run src/main.ts # reads storage/key_value_stores/default/INPUT.json