Understat xG League & Team Stats Scraper avatar

Understat xG League & Team Stats Scraper

Pricing

Pay per event

Go to Apify Store
Understat xG League & Team Stats Scraper

Understat xG League & Team Stats Scraper

Scrape expected goals (xG), xGA, NPxG, PPDA and full standings for all 6 understat.com leagues across any available season. One row per team per season, aggregated from match-level history.

Pricing

Pay per event

Rating

0.0

(0)

Developer

BowTiedRaccoon

BowTiedRaccoon

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Share

Scrape expected goals (xG), non-penalty xG (NPxG), xGA, PPDA, deep completions, and full W/D/L standings from understat.com — the canonical open xG data source for European football.

Covers all 6 understat leagues (EPL, La Liga, Bundesliga, Serie A, Ligue 1, RFPL) across every available season (2014–present). One aggregated row per team per season.

Features

  • 6 leagues in a single run: EPL, La Liga, Bundesliga, Serie A, Ligue 1, RFPL
  • All seasons from 2014/2015 onwards — back-fill historical data or track the current season
  • Match-level aggregation — sums each team's per-match xG, xGA, NPxG, PPDA, deep completions into a clean season total
  • PPDA ratio computed correctly as passes_attempted / defensive_actions (lower = more pressing)
  • No proxy required — understat.com is open and datacenter-friendly

Use Cases

  • Build football analytics dashboards (xG vs actual goals by team)
  • Feed betting or fantasy football models with expected-goals standings
  • Compare xG performance across leagues or seasons for research / Substack writing
  • Backtest xG-based table predictions

Input

FieldTypeDefaultDescription
leaguesarray(all 6)Which leagues to scrape. Valid values: EPL, La_liga, Bundesliga, Serie_A, Ligue_1, RFPL
seasonsarray["2024"]Season start years to scrape. E.g. ["2024"] = 2024/2025, ["2023","2024"] = two seasons
maxItemsinteger10Maximum records to return (0 = unlimited)

Example input — EPL last 3 seasons

{
"leagues": ["EPL"],
"seasons": ["2022", "2023", "2024"],
"maxItems": 0
}

Example input — All leagues, current season

{
"leagues": ["EPL", "La_liga", "Bundesliga", "Serie_A", "Ligue_1", "RFPL"],
"seasons": ["2024"],
"maxItems": 0
}

Output

One record per team per season:

{
"season": "2024/2025",
"league": "EPL",
"team_name": "Aston Villa",
"team_id": "71",
"games_played": 38,
"wins": 19,
"draws": 9,
"losses": 10,
"goals_for": 58,
"goals_against": 51,
"xg_for": 66.39,
"xg_against": 55.0,
"npxg": 61.71,
"deep": 285,
"ppda": 12.39,
"oppda": 9.96,
"points": 66,
"source": "https://understat.com/league/EPL"
}

Field reference

FieldDescription
seasonSeason label (e.g. 2024/2025)
leagueLeague name
team_nameTeam name as shown on understat.com
team_idUnderstat internal team ID
games_playedTotal matches played
wins / draws / lossesSeason record
goals_for / goals_againstGoals scored / conceded
xg_forTotal expected goals (xG)
xg_againstTotal expected goals against (xGA)
npxgNon-penalty xG (excludes spot-kick quality)
deepDeep completions — passes into the opposition's danger zone
ppdaPasses per defensive action by opponent (lower = team presses more aggressively)
oppdaOpponent PPDA — how much the team is pressed
pointsTotal league points
sourceSource URL

Notes

  • Data is sourced from understat.com's internal XHR API (/getLeagueData/{league}/{season}), which returns gzip-compressed JSON. All values are aggregated from per-match history.
  • PPDA and OPPDA are null if a team played 0 defensive actions (extremely rare, data gap seasons only).
  • The RFPL (Russian Premier League) data coverage may be incomplete for recent seasons.
  • maxItems counts across all requested league × season combinations. Set to 0 to scrape everything.