How douglasbc/scraping-understat-dataset works
1. This repository is a data acquisition and packaging project, not an application runtime. Its main purpose is to scrape Understat and publish cleaned CSV datasets for football/soccer analytics.
2. The external system boundary is Understat.com. All primary data originates there and is pulled into the repo by Python scraping scripts, then stored locally as versioned CSV outputs.
3. The scraping subsystem lives under scraping/. It is split into:
- season_scraper.py for season-level collection,
- match_scraper.py for match-level collection,
- update.py as the orchestration entry point for refreshing the dataset.
4. The update workflow appears to be incremental rather than a one-off export. The README says to place scraping and datasets side by side and run update.py, which suggests the script reads existing CSVs, fetches new Understat data, and appends or refreshes files in place.
5. League-specific configuration is isolated in scraping/teams_set/. Each text file contains team lists for one competition:
- EPL
- La Liga
- Bundesliga
- Serie A
- Ligue 1
- RFPL
These files likely provide name normalization and league scoping for the scraper.
6. The repository’s core data products are under datasets/, organized first by league and then by season. For each league there are paired outputs:
- players_<league>_<season>.csv
- shots_<league>_<season>.csv
Seasons run from 14-15 through 21-22.
7. There is also a repository-wide aggregate file at datasets/shots_dataset.csv, which likely combines all leagues and seasons into one shots table for downstream analysis. The per-league directories provide the modular source-of-truth slices.
8. The data model is split into two domains:
- shot-level event data, which is the main Understat xG dataset,
- player-season summary data, which captures season stats for players involved in those matches.
The separate file families indicate different row grains and should be diagrammed as distinct dataset outputs.
9. Documentation is handled separately in documentation/ through PDF data dictionaries for shots and players. This is the schema/semantics boundary for analysts who consume the CSVs.
10. requirements.txt defines the Python runtime dependencies for the scraping pipeline. No web service, database, or queueing system is present in the repo; the architecture is a local Python ETL-style workflow that writes flat files.
11. scraping/empty_url_update.txt suggests there is some operational bookkeeping for missing or unresolved Understat URLs during updates. That implies the scraper includes failure handling or partial-refresh behavior.
12. For an architecture diagram, the clearest flow is: Understat source site -> Python scraping/update scripts -> league/team configuration -> per-league/per-season CSV outputs -> combined datasets and documentation for consumers.
Main entry points: match_scraper.py Match scraper · season_scraper.py Season scraper · update.py Update script · shots_data_dictionary.pdf Shots dictionary
Components 16
External source
Primary data origin outside the repository.
- Understat · Source site for football match and player data.
Scraping pipeline
Python ETL flow that refreshes and normalizes Understat data.
- Update script · Entry point that refreshes datasets incrementally.
scraping/update.py - Season scraper · Collects season-level player data from Understat.
scraping/season_scraper.py - Match scraper · Collects match-level shot data from Understat.
scraping/match_scraper.py - Team lists · League-specific team lists used for scoping and name normalization.
scraping/teams_set - URL log · Bookkeeping for unresolved or missing Understat URLs during updates.
scraping/empty_url_update.txt - Dependencies · Python packages required to run the scraping pipeline.
requirements.txt
Data products
Versioned CSV datasets and analyst-facing documentation.
- Shots dataset · Repository-wide combined shots table across leagues and seasons.
datasets/shots_dataset.csv - EPL outputs · Per-season player and shot CSV outputs for the EPL.
datasets/epl - La Liga outputs · Per-season player and shot CSV outputs for La Liga.
datasets/la_liga - Bundesliga outputs · Per-season player and shot CSV outputs for Bundesliga.
datasets/bundesliga - Serie A outputs · Per-season player and shot CSV outputs for Serie A.
datasets/serie_a - Ligue 1 outputs · Per-season player and shot CSV outputs for Ligue 1.
datasets/ligue_1 - RFPL outputs · Per-season player and shot CSV outputs for RFPL.
datasets/rfpl - Shots dictionary · PDF data dictionary for shot-level CSV fields and semantics.
documentation/shots_data_dictionary.pdf - Players dictionary · PDF data dictionary for player-season CSV fields and semantics.
documentation/players_data_dictionary.pdf
Connections 35
- Understat → Update script: source data · The update workflow pulls fresh data from Understat.
- Update script → Season scraper: invokes · Refresh orchestration delegates season-level collection.
- Update script → Match scraper: invokes · Refresh orchestration delegates match-level collection.
- Update script → Team lists: uses · League team lists guide normalization and scoping.
- Update script → URL log: records issues · Missing or unresolved URLs are tracked during updates.
- Update script → Dependencies: depends on · Python runtime dependencies support the scraping pipeline.
- Season scraper → Understat: scrapes · Season-level data is collected from the external site.
- Match scraper → Understat: scrapes · Match-level shot data is collected from Understat.
- Season scraper → Team lists: normalizes · Team lists help map league-specific names.
- Match scraper → Team lists: normalizes · Team lists help map league-specific names.
- Season scraper → EPL outputs: writes · League-season player CSV outputs are produced for EPL.
- Season scraper → La Liga outputs: writes · League-season player CSV outputs are produced for La Liga.
- Season scraper → Bundesliga outputs: writes · League-season player CSV outputs are produced for Bundesliga.
- Season scraper → Serie A outputs: writes · League-season player CSV outputs are produced for Serie A.
- Season scraper → Ligue 1 outputs: writes · League-season player CSV outputs are produced for Ligue 1.
- Season scraper → RFPL outputs: writes · League-season player CSV outputs are produced for RFPL.
- Match scraper → EPL outputs: writes · League-season shot CSV outputs are produced for EPL.
- Match scraper → La Liga outputs: writes · League-season shot CSV outputs are produced for La Liga.
- Match scraper → Bundesliga outputs: writes · League-season shot CSV outputs are produced for Bundesliga.
- Match scraper → Serie A outputs: writes · League-season shot CSV outputs are produced for Serie A.
- Match scraper → Ligue 1 outputs: writes · League-season shot CSV outputs are produced for Ligue 1.
- Match scraper → RFPL outputs: writes · League-season shot CSV outputs are produced for RFPL.
- Match scraper → Shots dataset: consolidates · Per-league shot slices feed the combined shots dataset.
- EPL outputs → Shots dictionary: described by · Data dictionary documents shot CSV semantics.
- EPL outputs → Players dictionary: described by · Data dictionary documents player CSV semantics.
- La Liga outputs → Shots dictionary: described by · Data dictionary documents shot CSV semantics.
- La Liga outputs → Players dictionary: described by · Data dictionary documents player CSV semantics.
- Bundesliga outputs → Shots dictionary: described by · Data dictionary documents shot CSV semantics.
- Bundesliga outputs → Players dictionary: described by · Data dictionary documents player CSV semantics.
- Serie A outputs → Shots dictionary: described by · Data dictionary documents shot CSV semantics.
- Serie A outputs → Players dictionary: described by · Data dictionary documents player CSV semantics.
- Ligue 1 outputs → Shots dictionary: described by · Data dictionary documents shot CSV semantics.
- Ligue 1 outputs → Players dictionary: described by · Data dictionary documents player CSV semantics.
- RFPL outputs → Shots dictionary: described by · Data dictionary documents shot CSV semantics.
- RFPL outputs → Players dictionary: described by · Data dictionary documents player CSV semantics.