Basketball Reference Table Scraper
Pricing
from $16.00 / 1,000 basketball statistics rows
Basketball Reference Table Scraper
Extract normalized stats rows from public Basketball Reference player, team, league, and box-score tables.
Pricing
from $16.00 / 1,000 basketball statistics rows
Rating
0.0
(0)
Developer
Muhammad Afzal
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Basketball Reference Scraper
Free-plan limit: Apify free-plan runs can return at most 5 dataset records per run from this Actor, even if you request more.
Extract normalized statistics rows from public Basketball Reference player, team, league, season, and box-score pages. The Actor is designed for analysts, researchers, journalists, fantasy-basketball workflows, and data pipelines that need a small, clearly attributed slice of a public stats page.
The Actor makes one static HTML request per URL, reads ordinary tables and tables embedded inside HTML comments, and writes one dataset item per table row. It does not crawl discovered links, log in, access Stathead, solve challenges, or build a site-wide archive.
What it extracts
Each dataset item has a stable envelope while the statistics remain flexible enough for different Basketball Reference tables.
| Field | Meaning |
|---|---|
sourceUrl | Public Basketball Reference page containing the row |
pageType | player, team, league, boxscore, or other |
pageTitle / entityName | Page title and primary heading |
tableId / tableTitle | Source HTML table ID and caption |
rowNumber / rowKey | Row position and stable deduplication key |
rowLabel | First non-empty cell, often a season, player, or team |
data | Values keyed by Basketball Reference data-stat names |
links | Absolute source links keyed by the linked cell's data-stat name |
scrapedAt | UTC extraction timestamp |
Numeric cells become JSON numbers, blank or dash cells become null, and labels such as 2024-25 remain strings. Repeated in-table header rows are removed. Footer, partial-team, and total rows are excluded by default and can be enabled with includeSummaryRows.
When to use it
Use this Actor when you know the public page URL and want rows from one or more named tables. Common IDs include per_game_stats, totals_stats, advanced, roster, and page-specific box-score table IDs. If a requested ID is wrong, the run returns an EMPTY outcome and lists available table IDs in SUMMARY.
Do not use it for Stathead, authenticated pages, bulk mirroring, AI model training, or creating a database that competes with Sports Reference. Basketball Reference's current policies permit responsible use of individual pages subject to its terms, attribution, and rate limits; the user remains responsible for ensuring their intended use is permitted.
Input
| Field | Default | Notes |
|---|---|---|
startUrls | Stephen Curry player page | 1–20 public HTTPS Basketball Reference URLs |
tableIds | per_game_stats | Exact table IDs; ignored by extractAllTables |
extractAllTables | false | Extract every table on supplied pages, without crawling links |
includeSummaryRows | false | Include footer, total, and partial-team rows |
maxResults | 100 | Global 1–5000 row cap |
requestDelayMillis | 3200 | Minimum 3200 ms to remain under 20 requests/minute |
requestTimeoutSeconds | 30 | Per-page timeout, 10–60 seconds |
proxyConfiguration | no proxy | Optional stable Apify Proxy route when direct cloud traffic is blocked |
Example input:
{"startUrls": [{ "url": "https://www.basketball-reference.com/players/c/curryst01.html" },{ "url": "https://www.basketball-reference.com/teams/GSW/2025.html" }],"tableIds": ["per_game_stats", "advanced"],"includeSummaryRows": false,"maxResults": 250,"requestDelayMillis": 3200,"proxyConfiguration": { "useApifyProxy": false }}
API example:
curl -X POST "https://api.apify.com/v2/acts/YOUR_USERNAME~basketball-reference-scraper/runs?token=YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{"startUrls":[{"url":"https://www.basketball-reference.com/leagues/NBA_2025_per_game.html"}],"tableIds":["per_game_stats"],"maxResults":25}'
Keep tokens in secrets or request headers in production; do not commit them to source code.
Output example
{"sourceUrl": "https://www.basketball-reference.com/players/c/curryst01.html","pageType": "player","pageTitle": "Stephen Curry Stats, Height, Weight, Position, Draft Status and more","entityName": "Stephen Curry","tableId": "per_game_stats","tableTitle": "Per Game Table","rowNumber": 1,"rowKey": "2af44bb5a2ee71d1f79d","rowLabel": "2009-10","data": {"year_id": "2009-10","age": 21,"team_name_abbr": "GSW","games": 80,"pts_per_g": 17.5},"links": {"year_id": "https://www.basketball-reference.com/players/c/curryst01/gamelog/2010/"},"scrapedAt": "2026-08-29T12:00:00.000Z"}
The named SUMMARY key-value record reports DATA, EMPTY, BLOCKED, REJECTED, or FAILED, page and table counts, delivered records, and per-page warnings. Diagnostics never appear as fake dataset rows.
Pay-per-event pricing
Current Apify event prices and platform-usage treatment are listed in the dedicated Pricing section below.
A 100-row run costs up to $2 in Actor events. A one-row run costs $0.02. Platform or proxy usage may be charged separately only when the live Actor pricing surface says so. maxResults gives a predictable result-event ceiling, and the Actor never manually charges the synthetic start or dataset-item events.
If a caller sets Apify's run-level maxTotalChargeUsd, the Actor checks the remaining synthetic dataset-item budget before every write and stops cleanly when the cap is exhausted. SUMMARY.recordsDelivered and resultEvents count only rows actually written.
Reliability and responsible access
Sports Reference publishes a limit of 20 requests per minute for Basketball Reference and may block a session for up to a day after violations. This Actor uses a single request stream, enforces at least 3.2 seconds between page requests, caps inputs at 20 pages, performs no recursive crawling, and makes no hidden retry storm. HTTP 403, 429, challenges, timeouts, wrong table IDs, and page changes are classified in SUMMARY.
Direct static HTML is the default and cheapest route. If a cloud route is blocked, you can enable an authorized Apify Proxy configuration; the Actor keeps one stable proxy session. It does not defeat CAPTCHAs or other access controls. A blocked run returns zero fabricated rows and zero result events.
Respect Sports Reference's terms, data-use policy, and bot traffic limits. Credit Basketball Reference and the exact sourceUrl when publishing results. Do not use the output for prohibited AI training, bulk redistribution, or a material substitute for Sports Reference or its data providers.
For support, open an issue on the Actor's Apify page with the run ID, source URL, requested table IDs, and a redacted copy of SUMMARY.
Pricing
This Actor uses pay-per-event pricing. These are the current Apify Store event prices:
| Event | Price (USD) | When it is charged |
|---|---|---|
apify-default-dataset-item | FREE: $0.02; BRONZE: $0.02; SILVER: $0.02; GOLD: $0.016; PLATINUM: $0.016; DIAMOND: $0.016 | Basketball statistics row — One schema-valid Basketball Reference table row written to the default dataset. |
apify-actor-start | $0.005 | Actor Start — Charged when the Actor starts running. Number of events charged depends on Actor memory (one event per GB, minimum one event). — Charged once per run. |
Apify platform usage for this Actor run is included alongside the event prices above; no separate per-run platform-usage fee is passed to users.
This covers Apify platform usage for this Actor run. Other Apify products or usage outside this Actor run may still follow your account plan.