Hockey-Reference NHL Stats Scraper — Skaters & Goalies
Pricing
from $1.60 / 1,000 nhl stat records
Hockey-Reference NHL Stats Scraper — Skaters & Goalies
Scrape Hockey-Reference NHL stats for any season: skater points, goalie save percentage and GAA, or standings as JSON rows. USD 2.00 per 1,000 rows.
Pricing
from $1.60 / 1,000 nhl stat records
Rating
0.0
(0)
Developer
Muhammad Afzal
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
15 hours ago
Last modified
Categories
Share
Hockey-Reference NHL Stats Scraper turns a Hockey-Reference season page into clean JSON rows: every skater's goals, assists, points, plus-minus, shots and ice time, every goalie's wins, saves, goals-against average and save percentage, or the league standings. It is built for fantasy hockey players, analysts, bettors' research tools and data pipelines that need NHL stats as a table, and it costs USD 2.00 per 1,000 rows on the FREE tier (USD 0.002001 per row, USD 1.60 per 1,000 on GOLD).
You pick a season and a table. The Actor reads that one Hockey-Reference page and writes one row per player or team to an Apify dataset you can export as JSON, CSV or Excel or read through the API.
What NHL stats does it return?
Each dataset item is one row of the season table you chose. All rows share the same fields, and fields that do not apply to the table are null.
| Field | Skaters | Goalies | Standings |
|---|---|---|---|
statType, season | yes | yes | yes |
rank | scoring rank | rank | standings position |
player, playerId | name and Hockey-Reference ID (kucheni01) | name and ID | null |
team, pos, age | team code, position, age | team code, G, age | full team name only |
games | games played | games played | null |
goals, assists, points | yes | yes (goalie points) | null |
plusMinus, pim, shots, shotPct, toiAvg | yes (shotPct in percent, toiAvg as mm:ss) | pim only | null |
starts, wins, losses, ties | null | yes (ties holds the ties/overtime column) | null |
goalsAgainst, saves, gaa, savePct, shutouts | null | yes (savePct as a fraction, e.g. 0.925) | null |
record | null | null | overall record, e.g. 56-22-4 |
sourceUrl, scrapedAt | yes | yes | yes |
The run also writes an OUTPUT record with the status (COMPLETED, EMPTY, BLOCKED, REJECTED or FAILED), the season, the table, the row count, the source URL and any warnings.
How do I scrape NHL player stats for a season?
Set year to the season's ending year and choose statType. The default returns the first 100 rows of the 2024-25 skaters table, in Hockey-Reference's order.
| Input | Default | Notes |
|---|---|---|
year | 2025 | Season ending year, so 2025 is 2024-25; 1918 to the current season |
statType | skaters | skaters, goalies or standings |
maxResults | 100 | Rows to return, 1–2,000; the 2024-25 skaters table has 1,251 rows |
The whole 2024-25 goalie table:
{ "year": 2025, "statType": "goalies", "maxResults": 200 }
Every skater row for the 2023-24 season:
{ "year": 2024, "statType": "skaters", "maxResults": 2000 }
How do I get NHL goalie stats and standings?
Use statType: "goalies" for the goalie table (122 rows for 2024-25) or statType: "standings" for the league table (32 teams with rank and overall record). Each run reads one table, so run the Actor once per table you need, or schedule several saved inputs.
Is there a Hockey-Reference API or NHL stats API?
Hockey-Reference does not offer a public API, and this Actor gives you API access to its season tables instead. Call it from apify-client, the Apify REST API, a schedule or an AI agent and you get the same fields every time.
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('muhammadafzal/hockey-reference-nhl-stats-scraper').call({year: 2025,statType: 'skaters',maxResults: 50,});const { items } = await client.dataset(run.defaultDatasetId).listItems();for (const row of items) console.log(row.player, row.team, row.points);
Python:
import osfrom apify_client import ApifyClientclient = ApifyClient(os.environ["APIFY_TOKEN"])run = client.actor("muhammadafzal/hockey-reference-nhl-stats-scraper").call(run_input={"year": 2025,"statType": "goalies","maxResults": 25,})for row in client.dataset(run.default_dataset_id).iterate_items():print(row["player"], row["wins"], row["savePct"])
Use it from an AI assistant
Hockey-Reference NHL Stats Scraper works from Claude, ChatGPT, Cursor or any MCP client through Apify's MCP server. Add https://mcp.apify.com/?tools=muhammadafzal/hockey-reference-nhl-stats-scraper to your client and ask, for example: "Get the 2024-25 NHL goalie stats from Hockey-Reference and list the five goalies with the best save percentage among those with at least 40 starts." Rows are charged at the prices below, so ask for a row limit.
What does the output look like?
Rows parsed from the live 2024-25 Hockey-Reference pages on 2026-10-26: one full skater row, then a goalie row and a standings row with their null fields left out:
[{"statType": "skaters", "season": 2025, "rank": 1,"playerId": "kucheni01", "player": "Nikita Kucherov", "team": "TBL", "pos": "RW", "age": 31,"games": 78, "starts": null, "wins": null, "losses": null, "ties": null,"goals": 37, "assists": 84, "points": 121, "plusMinus": 22, "pim": 45,"shots": 265, "shotPct": 14, "toiAvg": "21:11","goalsAgainst": null, "saves": null, "gaa": null, "savePct": null, "shutouts": null, "record": null,"sourceUrl": "https://www.hockey-reference.com/leagues/NHL_2025_skaters.html","scrapedAt": "2026-10-26T14:13:16.208Z"},{"statType": "goalies", "season": 2025, "rank": 1,"playerId": "helleco01", "player": "Connor Hellebuyck", "team": "WPG", "pos": "G", "age": 31,"games": 63, "starts": 62, "wins": 47, "losses": 12, "ties": 3,"goalsAgainst": 125, "saves": 1539, "gaa": 2, "savePct": 0.925, "shutouts": 8,"sourceUrl": "https://www.hockey-reference.com/leagues/NHL_2025_goalies.html"},{"statType": "standings", "season": 2025, "rank": 1,"team": "Winnipeg Jets", "record": "56-22-4","sourceUrl": "https://www.hockey-reference.com/leagues/NHL_2025_standings.html"}]
How much do NHL stats cost?
The Actor uses pay-per-event pricing with platform usage included. You pay for each row written to the dataset, plus one start event per run at the default 256 MB memory.
| Event | FREE | BRONZE | SILVER | GOLD | PLATINUM | DIAMOND |
|---|---|---|---|---|---|---|
| NHL stat record (one dataset row) | USD 0.002001 | USD 0.00195 | USD 0.0019 | USD 0.0016 | USD 0.0016 | USD 0.0016 |
| Actor start (per started GB of allocated memory) | USD 0.006251 | USD 0.006094 | USD 0.005938 | USD 0.005 | USD 0.005 | USD 0.005 |
Worked totals on the FREE tier:
- 2024-25 standings, 32 rows: 32 × USD 0.002001 + USD 0.006251 = USD 0.070
- Full 2024-25 skaters table, 1,251 rows: 1,251 × USD 0.002001 + USD 0.006251 = USD 2.51
maxResults caps the row charge. Rejected input, missing pages and blocked responses write no rows, so only the start event is charged.
When should I use it, and when not?
Use it when you need a full NHL season table as data: fantasy draft prep, season-over-season comparisons, goalie workload analysis, or a dashboard that refreshes standings on a schedule.
Use something else when:
- You need basketball, baseball or WNBA tables: Basketball Reference Scraper, Baseball Reference Stats Scraper or WNBA Stats Scraper.
- You need live scores or match results: Flashscore Match Results Scraper.
- You need player career pages, game logs, team pages, playoff tables or advanced stats. This Actor reads only the regular-season skaters, goalies and standings tables.
- You want to mirror Hockey-Reference, train an AI model or build a competing stats database. Sports Reference's terms restrict those uses.
Limits and reliability
- One page per run: a single request to the season page, with up to three attempts on rate limits, server errors or network errors.
- Traded players: skaters and goalies who played for several teams appear once per team and once more on a combined row whose
teamis2TMor3TM. The 2024-25 skaters table has 1,251 rows for 1,022 players, 111 of them combined rows. Filter those rows out, or keep only them, depending on your analysis. - Old seasons: any season from 1918 is accepted. Columns a season's page does not have come back as
null, and a season with no page ends with zero rows and a warning inOUTPUT, with no row charges. - Order: rows keep Hockey-Reference's order, so
maxResults: 25on skaters gives the top 25 scorers.
FAQ
Does the NHL have a public API?
The NHL's own web endpoints are undocumented, have changed before, and are not shaped as season tables. This Actor returns Hockey-Reference's season tables in one consistent format instead.
Where can I get NHL stats as CSV?
Run this Actor and export the dataset. Apify exports to CSV, JSON, Excel or XML, and integrations can send it to Google Sheets.
Can it scrape a single player's page?
No. It reads league season tables only. Filter the skaters or goalies table by player or playerId to get one player's season line.
Why is shotPct 14 but savePct 0.925?
The Actor keeps each column as Hockey-Reference prints it: shooting percentage as a percent, save percentage as a fraction.
Does it include playoff stats?
No. Only the regular-season table on each page is read.
How fresh is the data?
The page is read when the run starts, so in-season tables reflect Hockey-Reference at that moment. Schedule the Actor for daily updates.
Related Actors
- Basketball Reference Scraper: NBA tables from Basketball Reference
- Baseball Reference Stats Scraper: MLB tables from Baseball Reference
- WNBA Stats Scraper: WNBA player and team stats
- Flashscore Match Results Scraper: match results across sports
- Goodreads Scraper: another public-data tool from the same developer
Legal and compliance
The Actor reads one public Hockey-Reference page per run without logging in, solving CAPTCHAs or bypassing access controls. Follow Sports Reference's terms of use, data-use policy and bot-traffic policy, and credit Hockey-Reference when you publish results. This tool is not affiliated with Sports Reference or the NHL, and this is not legal advice.
Last verified: 2026-10-26