ProCyclingStats Scraper
Pricing
from $3.00 / 1,000 results
ProCyclingStats Scraper
Scrape ProCyclingStats.com - professional road cycling race results, rider profiles, team rosters, and PCS/UCI rankings. No login or API key required.
Pricing
from $3.00 / 1,000 results
Rating
0.0
(0)
Developer
Crawler Bros
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Scrape ProCyclingStats.com — the leading professional road cycling statistics database. Fetch race and stage results, rider profiles and career stats, team rosters, and PCS/UCI ranking tables covering every discipline (GC, climbers, sprinters, time trial, one-day races, and more). HTTP-only, no login or API key required.
What this actor does
- Five modes:
raceResults,riderProfile,teamRoster,rankings,raceStartlist - Race results for any race, season, and stage/classification page (stage, prologue, or overall GC/one-day result)
- Race startlists with every entrant's bib number, team, nationality, and DNF/DNS/OTL/DSQ status if the race has concluded
- Rider profiles with date of birth, nationality, physical stats, specialty points, current team, and PCS/all-time ranking position
- Team rosters with every rider's nationality, age, and jersey number
- 36 ranking types across PCS ranking, PCS season stats, PCS career wins, UCI World Ranking, and rider specialties (climbers, sprinters, time trial, one-day races, and more), for both men elite and women elite categories
- Empty fields are omitted from every record
Output per race result (recordType = raceResult)
rank,bib,ageriderName,riderUrl,riderNationalityteam,teamUrlspecialty— rider's classified specialty for that result (e.g.Sprint,Climber)uciPoints,points,time,gcTimeLagraceName,raceSlug,raceYear,raceStage,raceDate,raceClassification,raceCategory,raceDistancesourceUrl,recordType: "raceResult",scrapedAt
Output per rider (recordType = rider)
name,riderSlug,dateOfBirth,agenationality,nationalityUrlweightKg,heightMplaceOfBirth,placeOfBirthUrlspecialtyPoints— object withoneDayRaces,gc,timeTrial,sprint,climber,hillsscorespcsRanking,allTimeRanking— current PCS ranking positionscurrentTeam,currentTeamUrlphotoUrlsourceUrl,recordType: "rider",scrapedAt
Output per team roster row (recordType = teamRider)
riderName,riderUrl,riderNationality,jerseyNumber,ageteamName,teamStatus,teamAbbreviation,teamLicenseCountry,teamSlugsourceUrl,recordType: "teamRider",scrapedAt
Output per startlist entrant (recordType = startlistRider)
bibriderName,riderUrl,riderNationalitystatus—DNF/DNS/OTL/DSQif PCS records a withdrawal; omitted for riders who started/finished normallyteam,teamUrlraceName,raceSlug,raceYear,raceDate,raceClassificationsourceUrl,recordType: "startlistRider",scrapedAt
Output per ranking row (recordType = ranking)
rank,prevRankname,nameUrl,entityType(rider/team/nation)team,teamUrl— rider's current team (individual rankings only)pointsrankingType,rankingCategorysourceUrl,recordType: "ranking",scrapedAt
Input
| Field | Type | Default | Description |
|---|---|---|---|
mode | string | raceResults | raceResults / riderProfile / teamRoster / rankings / raceStartlist |
raceSlug | string | tour-de-france | Race URL slug (mode=raceResults, raceStartlist) |
raceYear | integer | 2024 | Season year (mode=raceResults, raceStartlist) |
raceStage | string | stage-1 | Stage/result page: stage-1, gc, result, prologue, etc. (mode=raceResults) |
riderSlugs | array | ["tadej-pogacar"] | Rider URL slugs to look up (mode=riderProfile) |
teamSlugs | array | ["uae-team-emirates-2024"] | Team URL slugs including season year (mode=teamRoster) |
rankingType | string | individual | One of 36 ranking types; available options depend on rankingCategory (mode=rankings) |
rankingCategory | string | me | me (men elite) / we (women elite) (mode=rankings) |
maxItems | integer | 30 | Maximum number of records to return (1–500) |
proxyConfiguration | object | AUTO proxy | Apify proxy configuration. ProCyclingStats blocks direct requests from Apify's datacenter IPs; the free AUTO group resolves this automatically. |
Examples
Example: Tour de France stage 1 results
{"mode": "raceResults","raceSlug": "tour-de-france","raceYear": 2024,"raceStage": "stage-1","maxItems": 50}
Example: race startlist
{"mode": "raceStartlist","raceSlug": "tour-de-france","raceYear": 2024,"maxItems": 200}
Example: rider profile lookup
{"mode": "riderProfile","riderSlugs": ["tadej-pogacar", "jonas-vingegaard", "remco-evenepoel"]}
Example: team roster
{"mode": "teamRoster","teamSlugs": ["uae-team-emirates-2024"]}
Example: World Ranking, women elite
{"mode": "rankings","rankingType": "world-ranking","rankingCategory": "we","maxItems": 100}
Use cases
- Sports media — build live leaderboards and rider profile pages from race results
- Fantasy cycling apps — pull current rankings and rider specialty scores for team-building tools
- Sponsorship & talent scouting — track rider career trajectories and team rosters season over season
- Sports betting analytics — feed historical race results and rankings into prediction models
- Cycling journalism — automate post-stage results tables and season recaps
FAQ
What is the data source? All data comes from the public pages of ProCyclingStats.com, the most comprehensive free professional road cycling statistics database.
Is this actor affiliated with ProCyclingStats? No — this is an independent, third-party actor that reads publicly available pages. It is not affiliated with or endorsed by ProCyclingStats.
How do I find a race, rider, or team slug?
Visit the corresponding page on procyclingstats.com and copy the last part of the URL — e.g. procyclingstats.com/rider/tadej-pogacar → slug tadej-pogacar. Full URLs are also accepted directly in the riderSlugs / teamSlugs / raceSlug fields.
Why does raceStage vary by race?
Stage races (Grand Tours, week-long stage races) use stage-1, stage-2, … and gc for the general classification. One-day races (Classics, World Championships) use result. Some Grand Tours also have a prologue.
Why are some ranking rows missing a team field?
Team, nation, and race rankings only rank a single entity type and have no separate "current team" column, so team is omitted for those ranking types.
Why does rankingType only offer 2 categories (me/we) and why do some ranking types say "men only" / "women only"?
ProCyclingStats uses different, inconsistent internal ranking-type names for men's and women's cycling (e.g. men's wins-individual vs women's individual-wins), and for junior/national-team categories the site's ranking-type taxonomy could not be reliably verified. To guarantee correct data, only the men-elite and women-elite combinations that were confirmed to return real, category-matching results are exposed. If you pick a ranking type that doesn't apply to the selected category, the actor automatically falls back to individual for that category and logs the substitution — it will never silently return the wrong category's data.
How fresh is the data? Every run fetches the live page directly from procyclingstats.com at request time — there is no caching.
Why does opening a sourceUrl sometimes look blocked to automated tools?
procyclingstats.com fronts its pages with bot-fingerprinting that can reject simplistic HTTP clients (e.g. a bare curl request). Every sourceUrl returned by this actor loads normally in a real web browser.
Why do some riders have no age or specialtyPoints?
Retired or lesser-known riders sometimes have incomplete profile pages on the source site; fields that aren't present are simply omitted rather than returned as null or zero.