Blog de développement

Extraction et Validation des codes postaux

Dernière Modification le :
2024-01-13

Pour l'enregistrement automatisé des bons de commande, il va être intéressant d'identifier et extraire les codes postaux. Cela permettra de renseigner la base de données avec des données propres. Certes, sur un bon de commande on a normalement pu extraire un numéro de TVA, SIREN ou SIRET, quitte à le reconstruire. On ne peut toutefois pas exclure le cas de la commande faite pour un tiers (ex. une centrale d'achat au nom d'une grosse société) ni la livraison chez un particulier, en cas de fermerture pour vacances, etc.

L'expression régulière

On applique une expression régulière à la version texte (Extraction+OCR) du mail de commande.

					    

					    
				    
Pour la Belgique c'est
					    

					    
				    

Validation sur base de données officielle

Les candidats sont ensuite confrontés à leur existence éventuelle dans une base de données de codes postaux. La liste officielle des codes postaux est publique Lire → et Télécharger → (ma version se trouve dans le ZIP de ressources)

Le problème des Cedex

Avec la liste des codes postaux, on pourrait se croire sorti d'affaire. Erreur! Les entreprises document souvent des adresses avec des CEDEX. Le courrier sous CEDEX représente près de 15 % du trafic total en France : 220 000 clients (entreprises, collectivités) disposent d’un code propre. Ils sont donnés selon le choix du receveur du bureau postal qui les délivre...

On trouve quelques explication ici Lire →

Or, le CEDEX, géré par La Poste, en est sa propriété. Elle commercialise l'accès au répertoire CEDEXA...

Christian QUEST a proposé une solution astucieuse à ce problème: Les entreprises déclarent leur adresses de distribution dans le base SIRENE, qui, elle est publique. Il suffit donc de balayer (après nettoyage et correction des erreurs...) la base stock SIRENE. Il l'a fait pour vous en 2017, et c'est une base disponible au public. Par ailleurs, il a déposé le code utilisé pour la costruction de cette liste.

Liste des CEDEX: Tous les liens vers cette base sont brisés. Sauf un qui reste actif! Ce jeu de données est reconstitué à partir des données de la base SIRENE de l'INSEE. Il n'est donc potentiellement pas exhaustif, mais contient plus de 14000 correspondances CEDEX / LIBELLE / Code INSEE.

Il conviendrait peut-être de le reconstituer, ce qui pourrait être facilité par le fait que l'INSEE met a disposition son fichier STOCK. Zippé, il fait quand même 1,6 G (et 6G dézippé!) Lire la Documentation → et on peut télécharger en bas de page: Télécharger →

Decedexation avec France_CP_Cedex

Ce fichier cedex date de 2017... On en refait un nouveau

"c:/Windows\SysWOW64\csvtk.exe"  cat "E:\...\StockEtablissement_utf8.csv" \
 | "c:/Windows\SysWOW64\csvtk.exe" cut -I -f codePostalEtablissement,libelleCommuneEtablissement,codeCommuneEtablissement,codeCedexEtablissement,libelleCedexEtablissement -o "E:\...\France-Voies_CP_CC_CEDEX_LIBELLES.csv"

Ce code extrait les colonnes Code Postal, code Commune, Cedex et Noms de la Base Stock SIRENE: on passe ainsi de 6 Gb à 1 Gb de données en 2-3 minutes (csvtk est vraiment très performant!): on charge le stream avec CAT puis on sélectionne les colonnes avec CUT.

On garde cela en réserve... Pour dé-Cedexer, on n'a que faire des noms et libellés: on ne garde que les codes ... On ira même plus avant en supprimant aussi la colonne des codes communes de l'INSEE.

"c:/Windows\SysWOW64\csvtk.exe"  cat "E:\...\France-Voies_CP_CC_CEDEX_LIBELLES.csv" \
 | "c:/Windows\SysWOW64\csvtk.exe" cut -I -f codePostalEtablissement,codeCedexEtablissement -o "E:\...\France-Voies_CP_CEDEX.csv"

Le fichier ne pèse alors plus que 260 Mb: beaucoup d'adresses n'ont pas de Cedex... On les élimine par une expression régulière inversée, avec GREP , applicable sur les 2 colonnes: -f 1,2 , avec une expression régulière: -r , dont la pattern est : -p "^$" et sera inversée par : -v

"c:/Windows\SysWOW64\csvtk.exe" cat "E:\...\France-Voies_CP_CEDEX.csv" \
 | "c:/Windows\SysWOW64\csvtk.exe" grep -f 1,2 -r -p "^$" -v -o "E:\...\France-Voies_CP_CEDEX_UTILES.csv"

Il y a beaucoup de doublons... On réduit avec UNIQ, appliquée sur les 2 colonnes avec -f 1,2

"c:/Windows\SysWOW64\csvtk.exe" cat "E:\...\SIRENE_Via_CP_CEDEX_UTILES.csv" \
 | "c:/Windows\SysWOW64\csvtk.exe" uniq -f 1,2 -o "E:\...\FRANCE-VOIES_CP_CEDEX_UNIQUES.csv"

Il reste une poignée d'enregistrement mal formés, avec par ex. [ND], ou BP3, voire CEDEX ... On les élimine en imposant aux enregistrements d'être compsés de 5 chiffres, avec grep, applicables aux 2 colonnes avec -f 1,2 par une expression régulière -r, dont la pattern est: -p "[0-9]{5}".
A noter que le nom du fichier de sortie doit être différent de celui d'entrée.

"c:/Windows\SysWOW64\csvtk.exe" cat "E:\...\FRANCE-VOIES_CP_CEDEX_UNIQUES.csv" \
 | "c:/Windows\SysWOW64\csvtk.exe" grep -f 1,2 -r -p "[0-9]{5}" -o "E:\...\FRANCE-VOIES_CP_CEDEX_UNIQUES2.csv"

Enfin, on retire les noms de colonne, avec del-header

"c:/Windows\SysWOW64\csvtk.exe" cat "E:\...\FRANCE-VOIES_CP_CEDEX_UNIQUES2.csv" \
 | "c:/Windows\SysWOW64\csvtk.exe" del-header -o "E:\...\FRANCE-VOIES_CP_CEDEX_UNIQUES.csv"
Et, voilà le travail! En quelques minutes on réduit de 6 Giga à 187 K, facile à manipuler avec un tableur, FSO ou une base de données. Il contient 15866 couples CP/Cedex pour 12160. Errreur sur l'autre: 50603

https://www.upu.int/fr/Accueil

https://www.data.gouv.fr/fr/datasets/liste-des-cedex/#_

https://raw.githubusercontent.com/cquest/geocodage-spd/20ff02d9e44771eb817c0ff08b5ea54b7379e99b/insee-sirene/cedex.csv

https://raw.githubusercontent.com/cquest/geocodage-spd/master/insee-sirene/cedex.csv

le bon: https://data.europa.eu/data/datasets/58dcc236c751df4ecbb0235f?locale=en

Les bases

A noter: si le fichier XLSX utilise un autre séparateur que la virgule, comme la base des codes postaux, on ajoute l'argument " -s ";" ". "C:\MesLogiciels\xlsxio_xlsx2csv.exe" "C:\MesData\laposte_hexasmal.xlsx" -s ";"

https://www.76310.fr/cedexa/

La validation de la ligne adresse avec HEXAVIA ou un équivalent gratuit

HEXAVIA contient plus de 2 Millions de voies et 7 000 autres appellations des 36 600 communes de France. Les voies présentes dans le fichier sont les appellations officielles des voiries dénommées par les mairies, les appellations d'usage ... Il permet le contrôle adresse de la ligne 4 (libellé de voie). Chaque libellé de voie contenu dans le référentiel est divisé en trois parties : - Le mot directeur de la voie : dernier mot de la voie - Le libellé complet de la voie - Le type de voie. Le fichier appartient à La Poste et c'est payant!

La Poste propose une API: ControlAdresse Lire → . Il existe un accès gratuit, en Freemium, limité à 2000 Interrogations par Semestre, ce qui est un bon début! On peut probablement étendre cette limite en créant plusieurs comptes...

Un moyen de réduire au mieux le besoin à des serives payants ou 'Freemium' est de recycler l'astucieuse idée de XXX. Constituer une base locale, à partir de toutes les adresses listées dans le Stock SIRENE. Le fichier pèse 6 Giga, mais avec les bons outils, c'est faisable. Si vous ne trouvez pas cette voie, alors, c'est qu'aucune entreprise n'y a jamais déclaré d'établissement! Dans un contexte B2B, une telle base devrait être largement suffisante

Une alternative est de scrapper la page : https://www.laposte.fr/professionnel/outils/tester-une-adresse

https://public.opendatasoft.com/explore/dataset/correspondance-code-cedex-code-insee/information/?flg=fr

 "c:/Windows\SysWOW64\csvtk.exe"  cat "E:\...\StockEtablissement_utf8.csv" | "c:/Windows\SysWOW64\csvtk.exe" nrow
' // et ...
"c:/Windows\SysWOW64\csvtk.exe"  cat "E:\...\StockUniteLegale_utf8.csv" | "c:/Windows\SysWOW64\csvtk.exe" nrow  

Référentiel GRATUIT France-Voies

C'est le nom que j'ai donné à une réferentiel basé sur les données publiques: celles de l'INSEE. Hexavia étant un réferentiel propriétaire, on donne un nom sensiblement différent. Il est obtenu à partir du Stock INSEE.

Le fichier Stock nous interesse est celui des Etablisements (SIRET): il contient des adresses. . SIRET: 36.675.897 Etablissements! (actifs ou pas... ce qui pour collecter des adresses n'a pas d'importance) Lire et Télécharger →

Voici un code pour connaitre le nombre d'enregistrement:

 "c:/Windows\SysWOW64\csvtk.exe"  cat "E:\...\StockEtablissement_utf8.csv" \ 
 | "c:/Windows\SysWOW64\csvtk.exe" nrow actif
 

Pour notre propos, on retient d'abord les adresses principales. On pourrait ensuite compléter avec les données d'adresses secondaires. Elles sont très peu nombreuses ( 24968 vs 3737164, soit 0,7 % et 100% redondantes! )

Les étapes de constructions sont: Extraction des colonnes interessantes

"c:/Windows\SysWOW64\csvtk.exe"  cat "E:\...\StockEtablissement_utf8.csv" \
 | "c:/Windows\SysWOW64\csvtk.exe" cut -I -f libelleVoieEtablissement,codePostalEtablissement \
 | "c:/Windows\SysWOW64\csvtk.exe" uniq -I -f 1,2 -o "E:\...\SIRENE_Via_CP_Voies_Etablissements.csv" 

On accède au stream par la commande CAT, on sélectionne les colonnes libelleVoieEtablissement et codePostalEtablissement avec CUT (ici, on néglige la colonne : typeVoieEtablissement, qui n'apporte rien à la détection; elle est utile pour l'étape suivante de validation). On applique UNIQ pour ne garder qu'un exemplaire de code.

Il en résulte un fichier de 75 Mb avec 3737164 lignes

On extrait les voies d'une commune en sélectionant avec GREP et le code postal. Pour les cedex, on reconstruit une liste de Code Postaux, en dé-Cedexant grace au fichier en accès libre: correspondance-code-cedex-code-insee Lire et Télécharger → . On contruit d'abord une liste de code Insee, puis on convertit en code postal grace à Hexasmal

 "c:/Windows\SysWOW64\csvtk.exe" cat "E:\...\SIRENE_Via_CP_Voies_Etablissements.csv" \
 | "c:/Windows\SysWOW64\csvtk.exe" cut -I -f 2  | "c:/Windows\SysWOW64\csvtk.exe" uniq -I -f 1 \
 | "c:/Windows\SysWOW64\csvtk.exe"  nrow  

Le code ci dessus charge notre CSV avec CAT, ne garde que la colonne des codes Postaux avec CUT et -f 2 (c'est la colonne #2, qui devient donc #1), puis UNIQ sur cette colonne, enfin, NROW : Nous avons donc 3 millions (3737164) de 'voies' réparties sur 6298 codes Postaux soit env. 600 par code postal

Les codes postaux en Belgique

La Belgique a moins de communes que la France, et il faut garder en mémoire qu'une commune peut avoir 2 noms usuels, le Francophone et le Neerlandophone. Il y a 1132 codes postaux uniques en Belgique, certaines communes utilisent le même code postal. Il est composé de 4 chiffres

La poste belge fournit gracieusement un tableau Excell, en fait 2: celui en Francais Lire et Télécharger → et celui en Néerlandais Lire et Télécharger → . Les liens de téléchargement sont en bas de pages. Les fichiers.xls sont aussi das le ZIP des ressources

L'importation vers SQL serveur peut avoir des chausses-trappes. Voici une méthode qui marche: télécharger les 2 versions (FR et NL) du fichier par classement numérique (zipcodes_num_fr_new.xls). Transformer en CSV via LibreOffice. Importer dans SQL avec l'assistant Import FlatFile (mais pas avec flatFile de DTS, Import Data). Modifier les colonees pour codes Postal: Varchar (10) les autres Varchar (255). Dans SQL, ne conserver que les 2 colonnes: code postal et localité (renommé en Code_Postal, Nom_commune, pour ressembler à la base Française.). Le codage est UTF-8.

Les données sur les entreprises: https://kbopub.economie.fgov.be/kbo-open-data/affiliation/index et https://kbopub.economie.fgov.be/kbo-open-data/affiliation/xml/?files

https://fr.nowmsg.com/fr_postal_code.asp?CityName=87015

https://codes-postaux.cybo.com/france/87015-CEDEX-1_limoges/

XXX

INSEE Documentation API Sirene Services-V3.9.pdf est dans le dossier des ressources

https://www.data.gouv.fr/fr/datasets/base-sirene-des-entreprises-et-de-leurs-etablissements-siren-siret/

celui-ci marche pour de vrai: https://public.opendatasoft.com/explore/dataset/correspondance-code-cedex-code-insee/export/?flg=fr

Voir aussi: https://public.opendatasoft.com/explore/dataset/economicref-france-sirene-v3/information/?disjunctive.libellecommuneetablissement&disjunctive.etatadministratifetablissement&disjunctive.activiteprincipaleetablissement&disjunctive.sectionetablissement&disjunctive.soussectionetablissement&disjunctive.divisionetablissement&disjunctive.groupeetablissement&disjunctive.classeetablissement&disjunctive.sectionunitelegale&disjunctive.soussectionunitelegale&disjunctive.classeunitelegale&disjunctive.naturejuridiqueunitelegale