Un ordinateur exécute des milliards d'opérations par seconde. La personne assise devant, elle, refait les mêmes quinze manipulations tous les lundis matin : ouvrir quatre exports, supprimer les lignes vides, coller dans un classeur, renommer le fichier avec la date, l'envoyer à trois destinataires.
Python est présenté partout comme le langage de l'automatisation. Les tutoriels existent par milliers, la syntaxe s'apprend en quelques semaines, et pourtant beaucoup de gens capables d'écrire une boucle for continuent de ranger leurs fichiers à la souris. Le blocage se situe rarement dans le langage. Il tient au fait qu'une tâche de bureau ne ressemble pas à un exercice de cours : elle est floue, elle a des exceptions, elle dépend de fichiers qui changent de nom.
Ce qui suit part de cinq situations réelles, avec le code qui les traite et les garde-fous à poser autour. Les scripts tiennent tous en moins de quarante lignes et n'utilisent presque que la bibliothèque standard.
Le problème : trois heures par mois qui n'apparaissent nulle part
Une PME de vingt personnes exporte chaque vendredi les commandes de son outil de gestion. Quatre fichiers CSV, un par canal de vente. Quelqu'un les ouvre, vérifie que les colonnes sont dans le même ordre, corrige deux dates au format américain, empile le tout dans un classeur, ajoute une colonne de total, enregistre sous commandes-semaine-32.xlsx et envoie.
Quarante minutes, chaque vendredi. Sur quarante-quatre semaines travaillées, cela fait près de vingt-neuf heures, soit quatre journées entières passées à déplacer des colonnes. Personne ne les voit dans un tableau de bord parce qu'elles sont diluées en tranches de quarante minutes.
La même structure se retrouve dans mille contextes : le photographe qui renomme trois cents fichiers avant livraison, le comptable qui ressaisit des montants depuis des PDF, le développeur junior qui relance à la main les mêmes commandes de nettoyage avant chaque démonstration. Dans tous les cas il y a des entrées identifiables, une règle stable, une sortie attendue. C'est exactement la forme d'un script.
Le principe : entrées, règle, sortie, journal
Avant d'ouvrir un éditeur, il faut écrire la tâche en une phrase de la forme suivante : à partir de tel endroit, appliquer telle règle, produire tel résultat, et laisser une trace. Les quatre morceaux sont indispensables, et c'est le quatrième qu'on oublie systématiquement.
Deux règles de sécurité viennent avec ce schéma. La première : un script qui déplace, renomme ou supprime commence toujours par un mode simulation, où il affiche ce qu'il ferait sans rien toucher. La seconde : un script doit pouvoir tourner deux fois de suite sans casser son propre résultat. En vocabulaire technique on parle d'idempotence, et cette propriété évite la moitié des dégâts classiques.
Côté outils, la bibliothèque standard de Python couvre l'essentiel : pathlib pour les chemins, shutil pour copier et déplacer, csv pour les exports tabulaires, logging pour le journal. Les exemples ci-dessous tournent sur Python 3.14, la version stable en 2026, mais rien n'y dépend d'une nouveauté récente.
Cinq scripts et leur code
1. Ranger un dossier fouillis par type de fichier
Le dossier Téléchargements finit toujours par contenir quatre cents éléments mélangés. Le script parcourt le dossier, crée un sous-dossier par extension et déplace chaque fichier dedans.
from pathlib import Path
import shutil
SOURCE = Path.home() / "Downloads"
SIMULATION = True
for fichier in SOURCE.iterdir():
if not fichier.is_file():
continue
extension = fichier.suffix.lower().lstrip(".") or "sans-extension"
destination = SOURCE / extension
cible = destination / fichier.name
if cible.exists():
print(f"deja present, ignore : {fichier.name}")
continue
print(f"{fichier.name} -> {extension}/")
if not SIMULATION:
destination.mkdir(exist_ok=True)
shutil.move(fichier, cible)
La variable SIMULATION sert de frein à main. On lance une première fois avec True, on lit la liste affichée, et on repasse à False seulement si le résultat annoncé correspond à l'intention.
2. Fusionner plusieurs exports CSV en un seul fichier propre
Reprenons la PME du début. Quatre fichiers, les mêmes colonnes, un en-tête à ne garder qu'une fois, et une colonne d'origine à ajouter pour savoir d'où vient chaque ligne.
import csv
from pathlib import Path
from datetime import date
DOSSIER = Path("exports")
SORTIE = Path(f"commandes-{date.today():%Y-%m-%d}.csv")
lignes = []
colonnes = None
for fichier in sorted(DOSSIER.glob("*.csv")):
with fichier.open(encoding="utf-8-sig", newline="") as f:
lecteur = csv.DictReader(f, delimiter=";")
if colonnes is None:
colonnes = lecteur.fieldnames + ["source"]
for ligne in lecteur:
ligne["source"] = fichier.stem
lignes.append(ligne)
with SORTIE.open("w", encoding="utf-8-sig", newline="") as f:
ecrivain = csv.DictWriter(f, fieldnames=colonnes, delimiter=";")
ecrivain.writeheader()
ecrivain.writerows(lignes)
print(f"{len(lignes)} lignes ecrites dans {SORTIE}")
Deux détails valent le détour. L'encodage utf-8-sig gère le marqueur invisible que Windows place en tête des CSV exportés depuis Excel, et le séparateur point-virgule est celui que produisent les tableurs configurés en français. Ces deux lignes évitent la majorité des accents cassés et des colonnes empilées dans une seule cellule.
3. Renommer en masse selon une règle
Trois cents photos à livrer sous la forme mariage-dupont-001.jpg. La règle est simple, le volume rend l'opération manuelle absurde.
from pathlib import Path
DOSSIER = Path("livraison")
PREFIXE = "mariage-dupont"
SIMULATION = True
photos = sorted(DOSSIER.glob("*.jpg"), key=lambda p: p.stat().st_mtime)
for index, photo in enumerate(photos, start=1):
nouveau_nom = f"{PREFIXE}-{index:03d}{photo.suffix.lower()}"
if photo.name == nouveau_nom:
continue
print(f"{photo.name} -> {nouveau_nom}")
if not SIMULATION:
photo.rename(photo.with_name(nouveau_nom))
Le tri par date de modification garantit que la numérotation suit l'ordre de prise de vue et pas l'ordre alphabétique du nom d'origine, qui place souvent IMG_10 avant IMG_9. Le continue quand le nom est déjà bon rend le script rejouable sans dégât.
4. Extraire des données d'une pile de PDF
Des factures fournisseurs arrivent en PDF, il faut le numéro et le montant dans un tableau. Ici on sort de la bibliothèque standard, avec pdfplumber, qui s'installe par pip install pdfplumber.
import csv
import re
from pathlib import Path
import pdfplumber
NUMERO = re.compile(r"Facture\s+n[°o]\s*([A-Z0-9-]+)")
MONTANT = re.compile(r"Total TTC\s*:?\s*([\d\s,\.]+)")
resultats = []
for pdf_path in sorted(Path("factures").glob("*.pdf")):
with pdfplumber.open(pdf_path) as pdf:
texte = "\n".join(page.extract_text() or "" for page in pdf.pages)
numero = NUMERO.search(texte)
montant = MONTANT.search(texte)
resultats.append({
"fichier": pdf_path.name,
"numero": numero.group(1) if numero else "A VERIFIER",
"montant": montant.group(1).strip() if montant else "A VERIFIER",
})
with open("factures.csv", "w", encoding="utf-8-sig", newline="") as f:
ecrivain = csv.DictWriter(f, fieldnames=["fichier", "numero", "montant"], delimiter=";")
ecrivain.writeheader()
ecrivain.writerows(resultats)
La mention A VERIFIER plutôt qu'une case vide est un choix délibéré : elle rend les échecs visibles au premier tri du tableur. Un script d'extraction qui échoue en silence produit un fichier qui a l'air correct, et c'est la pire sortie possible. Cette méthode ne fonctionne que sur des PDF contenant du texte : un PDF scanné est une image, il faut alors passer par de la reconnaissance de caractères, ce qui est un autre chantier.
5. Produire un rapport et l'envoyer par mail
Dernier maillon de la chaîne : envoyer le résultat sans ouvrir de client de messagerie.
import os
import smtplib
from email.message import EmailMessage
from pathlib import Path
message = EmailMessage()
message["From"] = os.environ["SMTP_USER"]
message["To"] = "direction@exemple.fr"
message["Subject"] = "Commandes de la semaine"
message.set_content("Le recapitulatif hebdomadaire est en piece jointe.")
fichier = Path("commandes-2026-08-13.csv")
message.add_attachment(
fichier.read_bytes(),
maintype="text",
subtype="csv",
filename=fichier.name,
)
with smtplib.SMTP_SSL(os.environ["SMTP_HOST"], 465) as serveur:
serveur.login(os.environ["SMTP_USER"], os.environ["SMTP_PASSWORD"])
serveur.send_message(message)
Les identifiants sont lus dans les variables d'environnement, jamais écrits dans le fichier. C'est la différence entre un script qu'on peut poser sur un dépôt Git et un script qui finit par publier le mot de passe de la boîte mail de l'entreprise. Cette séparation entre le code et la configuration fait partie des points détaillés dans l'article sur les douze facteurs et les applications qui cassent en production.
Un avis qui ne fait pas l'unanimité : ce cinquième script est celui qu'il faut écrire en dernier. Envoyer un mail automatiquement est très satisfaisant et très dangereux, parce qu'une boucle mal écrite expédie quatre cents messages à un client réel avant que quiconque ait le temps de fermer le terminal. Écris d'abord le rapport dans un fichier, vérifie-le pendant deux semaines, ajoute l'envoi ensuite.
Faire tourner le script sans y penser
Un script lancé à la main reste une tâche manuelle, simplement plus rapide. La planification transforme le gain ponctuel en gain permanent.
Sur Linux et macOS, cron fait le travail. La commande crontab -e ouvre le fichier de planification, et une ligne suffit :
0 8 * * 5 /home/adel/projets/venv/bin/python /home/adel/projets/fusion.py >> /home/adel/logs/fusion.log 2>&1
Les cinq champs du début se lisent minute, heure, jour du mois, mois, jour de la semaine : ici tous les vendredis à huit heures. Les chemins sont absolus, ce qui n'est pas un détail de style. Sur Windows, le Planificateur de tâches offre la même fonction avec une interface graphique, en pointant vers l'exécutable Python de l'environnement virtuel. Ces automatismes système se pilotent beaucoup plus confortablement avec un minimum d'aisance dans le terminal, sujet couvert par la formation Linux et ligne de commande pour développeurs.
Les pièges qui coûtent cher
Le chemin relatif qui ne marche que depuis ton terminal
Un script lancé depuis son dossier trouve exports/. Le même script lancé par cron démarre depuis le répertoire personnel et ne trouve rien. La parade tient en une ligne, BASE = Path(__file__).resolve().parent, puis tous les chemins construits à partir de BASE. C'est une variante du symptôme décrit dans l'article "Ça marche sur ma machine".
Le script muet qui a cessé de tourner en mars
Sans journal, personne ne remarque qu'une automatisation s'est arrêtée. Le module logging configuré en trois lignes écrit chaque exécution avec sa date et le nombre d'éléments traités. Un fichier de log de deux kilo-octets vaut mieux qu'un mois de données manquantes découvert en octobre.
Les droits trop larges
Un script de lecture qui tourne avec un compte capable de supprimer la base entière transforme une faute de frappe en incident. Donner à chaque automatisation le strict nécessaire est un réflexe qui se prend tôt, développé dans l'article sur le principe de moindre privilège.
Automatiser un processus encore instable
Si la règle de nommage change tous les deux mois, le script devient un poids mort qu'il faut réécrire à chaque fois. Automatiser suppose une règle figée. Quand la règle bouge encore, le bon investissement consiste d'abord à la stabiliser avec les personnes concernées, puis à coder.
Le débogage remis à plus tard
Un script d'automatisation échoue toujours sur le cas particulier : le fichier verrouillé, la ligne vide, l'accent dans le nom. Savoir lire une trace d'erreur et isoler la cause fait gagner plus de temps que la maîtrise de la syntaxe, et cette méthode s'apprend, comme le détaille l'article apprendre à débugger.
Par où commencer selon son niveau
Sans aucune expérience de Python, le premier script du dossier rangé reste accessible en quelques heures à condition d'avoir vu les bases du langage : variables, boucles, conditions, fonctions. La formation Python pour débutants couvre ce socle.
Pour aller jusqu'aux scripts planifiés, aux fichiers Excel, aux appels d'API et à la gestion propre des erreurs, la formation Automatisation et scripting avec Python reprend exactement cette chaîne, du dossier à ranger jusqu'au rapport envoyé. Et quand les scripts commencent à se ressembler et à partager du code, il devient rentable de les structurer en objets et en modules, ce que traite Python : POO et traitement de données. Le catalogue Python et Data détaille la suite du parcours, jusqu'aux API et au machine learning.
Les personnes en reconversion, les développeurs juniors et les curieux non informaticiens ont ici un avantage particulier : un script qui résout un vrai problème du quotidien est aussi un excellent élément de portfolio, souvent plus parlant qu'un clone de site de tutoriel, comme le montre l'article sur le premier projet à mettre sur un CV de développeur junior.
Reste à choisir la première tâche. Le meilleur candidat n'est pas la plus longue, c'est celle dont la règle tient en une phrase et que personne n'aime faire.