Transfermarkt League Table & Club Values Scraper avatar

Transfermarkt League Table & Club Values Scraper

Pricing

from $3.00 / 1,000 competition club scrapeds

Go to Apify Store
Transfermarkt League Table & Club Values Scraper

Transfermarkt League Table & Club Values Scraper

Scrape any Transfermarkt competition by code: full league table plus every club's squad size, average age, foreigners and total market value — merged into one row per club. Works for leagues and cups, any season. No API key, no login, no proxy needed. JSON, CSV or Excel.

Pricing

from $3.00 / 1,000 competition club scrapeds

Rating

0.0

(0)

Developer

Elena Vance

Elena Vance

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

5 days ago

Last modified

Share

Scrape any competition on Transfermarkt by its code — GB1, ES1, L1, IT1, CL — and get one row per club that merges the league table with what the squad is worth.

Rank, points, wins, draws, losses and goals on the same row as squad size, average age, foreigners and total market value. No join, no second run.

Works for leagues and cups, any season. No API key, no login, no residential proxy, no browser. It runs on the Apify free plan. Export to JSON, CSV, Excel, XML or pull it from the API.


What you get

One row per club. Real, unedited output from {"competitionCodes": ["GB1"], "season": 2025}:

FieldValue
competitionCode / competitionNameGB1 / Premier League
competitionTypeleague
competitionCountry / competitionTierEngland / First Tier
reigningChampionArsenal FC
numberOfTeams / numberOfPlayers20 / 571
averageMarketValuePerPlayer23100000
averageAge26.0
season / seasonStartYear25/26 / 2025
clubId / clubName11 / Arsenal FC
squadSize40
clubAverageAge23.9
foreignersCount20
averageMarketValue33150000
totalMarketValue1330000000
rank1
matchesPlayed38
wins / draws / losses26 / 7 / 5
goalsFor / goalsAgainst / goalDifference71 / 27 / 44
points85
clubUrlhttps://www.transfermarkt.com/x/startseite/verein/11

The table and the club values arrive merged. On Transfermarkt these are two different pages; here they are one row, so "which of the top six is overachieving against its squad value" is a spreadsheet sort rather than a data project.

Money is parsed, not passed through

€1.33bn becomes 1330000000 and €33.15m becomes 33150000. The data sorts, sums and filters without a cleaning pass.


Leagues and cups both work — and they carry different data

A cup has no league table. Transfermarkt does not publish one, so this Actor does not invent one:

League (GB1, ES1, L1…)Cup (CL, EL, DFB…)
rank, points, wins, goalsnull
squadSize, totalMarketValue, clubAverageAge
foreignersCountnull
numberOfTeams, competitionTier, reigningChampionnull
Typical rows18–2436

The columns stay the same either way — a cup row carries the standings fields as nulls rather than dropping them, so a mixed export is still a clean table in Excel. The run's status message says how many of your competitions were cups, so an all-null standings column is never a mystery.

You do not have to tell the Actor which kind you asked for. It finds out from Transfermarkt's own redirect and takes the right path.


Input

{
"competitionCodes": ["GB1", "ES1", "CL"],
"season": 2025,
"includeStandings": true,
"maxItems": 500
}
InputWhat it does
competitionCodesTransfermarkt competition codes, or any Transfermarkt competition URL. The name in the URL is ignored.
seasonThe year a season starts2025 is 2025/26. Leave empty for the current season.
includeStandingsMerge the league table in. One extra request per league, no extra charged rows. Off means the standings fields come back null.
maxItemsHard cap on charged rows. Default 500.
proxyConfigurationLeave it off — see below.

Codes worth knowing

CodeCompetitionCodeCompetition
GB1Premier LeagueCLUEFA Champions League
ES1LaLigaELUEFA Europa League
L1BundesligaUCOLUEFA Conference League
IT1Serie AGB2Championship
FR1Ligue 1NL1Eredivisie
PO1Liga PortugalTR1Süper Lig
BRA1BrasileirãoMLS1Major League Soccer
AR1NLiga ProfesionalSA1Saudi Pro League

Any code from a Transfermarkt URL works: the segment after /wettbewerb/ or /pokalwettbewerb/.

Cost lever

One competition is 18–36 charged rows, not one. A domestic league is 18–24; the Champions League is 36. Five leagues is roughly 100 rows.

includeStandings costs an extra request, never an extra row — the table is merged onto rows you are being charged for anyway.


Why this is cheap to run

Transfermarkt is fronted by AWS WAF, and the usual answer — a residential proxy at $8/GB — is what makes scrapers of this site expensive. It turns out Apify's own egress is not challenged, so this Actor calls Transfermarkt directly and pays nothing for proxy. A residential IP is fetched only if a request is genuinely challenged, and most runs never touch one.

One competition is one or two page loads for 20–36 rows, which makes this the cheapest way to get Transfermarkt data per row that exists in this suite.

That is also why the Actor start fee is $0.00005 and the default memory is 256 MB. Apify charges the start fee once per gigabyte, so a 4 GB Actor with a $0.10 start fee bills $0.40 before returning a single row. Several Transfermarkt scrapers on the Store do exactly that.

Do not turn on Apify's datacenter proxy. Transfermarkt's WAF challenges Apify's datacenter pool while leaving its direct egress alone — verified, same URLs, same second — so switching it on takes a working run and breaks it.


What makes this different

  • The table and the squad values on one row. Everywhere else these are two scrapes and a join on club name, which breaks on Arsenal FC vs Arsenal. Here they are merged by club ID, so mid-season disagreements between the two tables cannot mis-pair a single row.
  • Cups are supported properly, from their own entrant page, with the standings fields explicitly null rather than quietly absent.
  • clubId is the input to the squad scraper. One run gives you every club in a league; feed those IDs to the Transfermarkt Club Squad Scraper and you have every player in the league.
  • The season returned is the season reported. season is read back off the page, never echoed from your input, and requestedSeason sits beside it — Transfermarkt silently serves its newest season for a future year, and this is how you can see that it did.
  • A code Transfermarkt doesn't have returns an unbilled COMPETITION_NOT_FOUND row, not silence and not a failed run. Transfermarkt answers an unknown code with HTTP 200 and its full competition index; this Actor reads the redirect rather than the status code.
  • You are never billed for a failure, and bad input returns an INVALID_INPUT row instead of failing the run.
  • A weekly canary runs the deployed build against live Transfermarkt — two leagues and a cup — and opens a GitHub issue if field coverage drops.

What this Actor does NOT return

  • Players. Squad size and total value, yes; the players themselves are one request per club — that is the Transfermarkt Club Squad Scraper, which takes the clubId this Actor returns.
  • Fixtures, results or match reports. This is the table, not the schedule.
  • Cup brackets or round-by-round progress. A cup returns its entrants.
  • A league table for a cup, because Transfermarkt does not have one. Group stages are not published as one table.
  • Anything requiring a Transfermarkt login.

Example runs

One league, current season:

{ "competitionCodes": ["GB1"] }

Europe's big five, a past season:

{
"competitionCodes": ["GB1", "ES1", "L1", "IT1", "FR1"],
"season": 2024
}

Every Champions League entrant and what their squad is worth:

{ "competitionCodes": ["CL"] }

Club values only, at half the requests:

{ "competitionCodes": ["GB1", "ES1"], "includeStandings": false }

Part of a Transfermarkt suite:

  • Transfermarkt Player & Market Value Scraper — one player in depth, with the full market-value and transfer histories.
  • Transfermarkt Club Squad Scraper — every player in a club's squad, with the fee each was signed for.
  • Transfermarkt League Table & Club Values Scraper — this one.
  • Transfermarkt Transfers Scraper — transfer feeds by club, competition or the global latest-transfers stream.

They chain: this Actor's clubId is the squad scraper's input, and the squad scraper's playerId is the player scraper's input.