Aller au contenu
Marc Steven Mouthoud / data engineering
Projet 04 · Ingestion quotidienne

prix-carburants.gouv.fr · Licence Ouverte

Prix des carburants

10 230 stations · historique depuis 2025

Trouvez la station la moins chère autour de vous. Les prix de toutes les stations de France, relevés chaque matin par un pipeline qui garde chaque changement de prix.

Prix du 7 novembre 2026 · 53/53 tests dbt · mis à jour chaque matin

Par exemple

Carburant
Rayon

Les stations les moins chères autour du lieu choisi s'afficheront ici.

Prix du 7 novembre 2026 ; les prix du matin se chargent à la première recherche. Votre position reste dans votre navigateur : les distances, à vol d'oiseau, sont calculées ici.

Prix du gazole, station par station, le 7 novembre 2026

La moins chère
2,008 €
Chauray (79)
La plus chère
2,701 €
Les Salles (42), autoroute
Sur autoroute
2,359 €
prix médian, contre 2,190 € partout
Chaque station est à ses coordonnées : la France n'est dessinée par rien d'autre. Prix du gazole de 7 jours ou moins ; les stations sans prix récent restent en gris. Un pic est d'autant plus haut que le litre dépasse 2,20 €, le prix médian arrondi. Cliquez sur la carte pour chercher autour d'un point.

Prix médian au litre, le 7 novembre 2026

  • Gazole8 957 stations2,19 €
  • SP986 822 stations2,14 €
  • SP952 295 stations2,10 €
  • E107 265 stations2,00 €
  • GPLc966 stations1,08 €
  • E852 653 stations0,89 €

L'histoire · 1

Un relevé n'est pas un changement

Le fichier officiel note le prix de chaque station plusieurs fois par jour, souvent sans qu'il ait bougé. Pour garder l'historique des vrais changements, il faut d'abord écarter les répétitions.

9 465 583relevés, 2025-2026
5 222 646vrais changements de prix

45 % des relevés répètent le prix précédent de la même station pour le même carburant. Parmi les changements restants, 2 748 854 hausses et 2 436 753 baisses, pour une variation médiane de 1,3 centime.

mart_changements_prix.sql (extrait)

select *
from {{ ref('stg_roulez_eco__prix') }}
qualify prix_litre is distinct from lag(prix_litre) over (
    partition by station_id, carburant_id
    order by maj_at
)

L'histoire · 2

Quelle heure est-il dans le fichier ?

Les relevés sont datés sans fuseau horaire. Heure de Paris ou UTC ? La réponse change l'ordre des relevés à chaque changement d'heure, et l'âge des prix affichés.

Compter les relevés entre 2 h et 3 h la nuit du passage à l'heure d'été ne prouve rien : même un dimanche ordinaire n'en compte aucun. La preuve vient d'un traitement automatique qui tourne chaque nuit à 01:17, heure de Paris, toute l'année. Le lendemain de chaque changement d'heure, il se décale une seule fois d'une heure, dans le sens attendu.

Fig. 01

raw.prix · relevés par tranche horaire

Le lot de 01:17 autour des changements d'heure 2025

Nuit01:10-01:2502:10-02:25Note
30 mars 20258050passage à l'heure d'été
31 mars 20250805lendemain
1 avril 20258134
26 octobre 20258890passage à l'heure d'hiver
27 octobre 202500lendemain : lot à 00:17
28 octobre 20258860
Relevés entre 01:10 et 01:25, et entre 02:10 et 02:25. Le 27 octobre, le lot a tourné à 00:17.

Les relevés sont donc lus en heure de Paris et stockés avec leur fuseau. La relecture du projet a trouvé un deuxième piège : compté sur une machine en UTC, comme les serveurs de GitHub Actions, 5 642 prix actuels auraient changé d'âge. Les jours sont désormais comptés explicitement à l'heure de Paris.

L'histoire · 3

Des prix d'essence dans la case E85

L'E85 coûte environ 0,85 € le litre. Pourtant, quelques stations y affichent des prix de 1,60 à 2,30 € : le prix de l'essence, saisi dans la mauvaise case.

Fig. 02

stg_roulez_eco__prix · 2025-2026

Relevés d'E85 au-dessus de 1,20 €

  • 1,2 €198
  • 1,3 €187
  • 1,4 €25
  • 1,5 €4
  • 1,6 €41
  • 1,7 €161
  • 1,8 €93
  • 1,9 €44
  • 2,0 €87
  • 2,1 €20
  • 2,2 €13
  • 2,3 €4
Un creux net à 1,50 € sépare les deux groupes : au-delà, le prix est marqué suspect. Même règle pour le GPLc au-delà de 1,80 €.
74prix actuels marqués suspects

Ils ne sont pas supprimés : l'information reste dans les données. Mais la recherche ne les classe jamais, pour ne pas désigner comme la moins chère une station sur la foi d'une erreur de saisie.

Sous le capot

Le pipeline

Chaque matin à 5 h UTC, GitHub Actions télécharge le fichier de l'année, reconstruit les couches, lance les tests et ne publie les prix que si tous réussissent.

  1. 01 · Source

    ZIP annuel, XML

    28,5 Mo, 322 Mo décompressé, ISO-8859-1

  2. 02 · Ingestion

    ingest.py

    Content-Type contrôlé, empreinte sha256, lecture en flux (iterparse)

  3. 03 · Raw

    Parquet par année

    14,2 Mo pour 2026, vues DuckDB

  4. 04 · Staging

    dbt, vues

    typage, heure de Paris, balises vides et conflits écartés

  5. 05 · Marts

    dbt, tables

    changements, stations, prix actuels · 53/53 tests

  6. 06 · Publication

    GitHub Pages

    prix_actuels.json, lu par cette page à chaque visite

Relevés chargés
9 465 583
fichiers 2025 et 2026
Changements de prix
5 423 584
Stations avec prix
10 230
Tests dbt
53/53
à chaque exécution

Dernière exécution : données du 7 novembre 2026. Relevés mesurés le 28 septembre 2026.

§ 01La sourceUn fichier par année, piégé de plusieurs façons

Le site officiel publie un fichier XML par année, qui contient chaque relevé depuis le 1er janvier, et un flux quotidien. Le flux quotidien n'est qu'une photo : un seul prix par station et par carburant. Seul le fichier annuel garde l'historique, et il sert à la fois à la reprise du passé et au chargement du matin.

  • Un faux succès. Pour une date indisponible, le serveur répond HTTP 200 avec une page HTML. Seul le Content-Type dit si l'on a reçu des données.
  • Un encodage ancien. Le XML est en ISO-8859-1 ; lu comme de l'UTF-8, il casse les accents des adresses.
  • Des stations sans prix. Sur 14 793 stations du fichier 2026, 9 774 ont publié au moins un prix. Les autres ont des coordonnées parfois fausses (à 0, latitude et longitude inversées) et sont écartées.
  • Pas de nom ni d'enseigne. Une station n'est connue que par son adresse et sa ville, écrites tantôt en majuscules, tantôt non.
§ 02La qualité53/53 tests, chacun vu en échec sur un défaut injecté

Chaque constat d'exploration devient un test dbt, relancé à chaque exécution. Un test mal écrit pouvant passer à tous les coups, un script injecte pour chacun des 18 tests singuliers un défaut précis, dans les données ou dans le code, et vérifie qu'il est détecté. Quelques exemples :

TestDéfaut injecté
assert_maj_toujours_lisibleun maj illisible (2025-13-45T25:00:00)
assert_aucun_releve_dans_le_futurun relevé daté après le téléchargement du fichier
assert_aucun_releve_pendant_heure_inexistanteun relevé à 02:30 la nuit du passage à l'heure d'été
assert_staging_conserve_les_relevesun filtre en trop : le SP98 disparaît
assert_prix_entre_0_30_et_4_eurosun prix en millièmes (1638 au lieu de 1.638)
assert_un_premier_releve_par_couplel'historique partitionné par station, sans le carburant
assert_prix_actuel_egal_dernier_changementle premier prix pris au lieu du dernier
assert_prix_suspects_rarestous les prix d'E85 passés à 1,99 €

La première exécution a trouvé un test inopérant : un prix en millièmes, le format des anciens fichiers, faisait planter la conversion avant que le test de plage ne s'exécute. Le type du prix a été élargi pour que ce soit le test qui signale le défaut.

§ 03Les décisions techniquesSans état, dans le navigateur, traçable
Réécrire l'année en cours chaque matin
Plutôt qu'un chargement incrémental, qui perdrait un relevé publié en retard. Environ une minute.
Une couche raw fidèle, en texte
Aucune conversion à l'ingestion : une valeur mal formée ne devient jamais un NULL silencieux. Le typage se fait dans dbt, versionné et testé.
Un pipeline sans état
Le serveur de GitHub Actions repart de zéro à chaque fois et reconstruit l'historique depuis la source officielle. Le ZIP de chaque semaine est archivé dans une release GitHub.
Les prix servis par GitHub Pages
Cette page lit prix_actuels.json à chaque visite : elle affiche les prix du matin sans être reconstruite. Si le fichier ne répond pas, elle se rabat sur la copie faite à son build.
La position reste dans le navigateur
Les distances sont calculées sur votre appareil, et la ville se retrouve parmi les stations elles-mêmes : aucun service de géolocalisation tiers.
§ 04Les limitesCe que les données ne disent pas
  • Des prix parfois anciens. Le dernier prix d'une station peut dater de plusieurs semaines : au-delà de 7 jours, il n'est classé que sur demande, et affiché grisé.
  • Les ruptures de stock ne sont pas chargées. Un carburant en rupture garde son dernier prix.
  • Des distances à vol d'oiseau, pas des temps de trajet.
  • Des adresses déclarées par les stations. Une ville ou un code postal se retrouve parmi les stations qui les déclarent, parfois à tort : la seule station du 13001 est en réalité dans le 11e arrondissement de Marseille. Les coordonnées, elles, sont justes, et les distances en dépendent seules.
  • La métropole et la Corse seulement. Aucune station d'outre-mer n'a publié de prix dans les fichiers.
  • Des seuils de prix suspects heuristiques, tirés de la distribution des prix, pas d'une règle officielle.
Tout le détail sur GitHub ↗