<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dev du Sud</title>
    <description>The latest articles on DEV Community by Dev du Sud (@devdusud).</description>
    <link>https://dev.to/devdusud</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4144889%2Fead5322a-de85-4109-8a26-f9854b867d52.jpg</url>
      <title>DEV Community: Dev du Sud</title>
      <link>https://dev.to/devdusud</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/devdusud"/>
    <language>en</language>
    <item>
      <title>Générer un PDF de rapport ou de facture sans acheter de logiciel</title>
      <dc:creator>Dev du Sud</dc:creator>
      <pubDate>Wed, 21 Oct 2026 22:14:54 +0000</pubDate>
      <link>https://dev.to/devdusud/generer-un-pdf-de-rapport-ou-de-facture-sans-acheter-de-logiciel-2ee2</link>
      <guid>https://dev.to/devdusud/generer-un-pdf-de-rapport-ou-de-facture-sans-acheter-de-logiciel-2ee2</guid>
      <description>&lt;h2&gt;
  
  
  Pourquoi générer un PDF soi-même
&lt;/h2&gt;

&lt;p&gt;Beaucoup de petites activités ont besoin de documents simples : une facture, un compte rendu d'intervention, un rapport de visite, un devis rapide, une fiche client. On peut le faire dans Word ou LibreOffice, bien sûr. Mais quand le même document revient souvent, remplir les mêmes lignes à la main devient vite pénible.&lt;/p&gt;

&lt;p&gt;Python peut générer un PDF automatiquement à partir de quelques informations : nom du client, date, lignes de prestation, total. Pas besoin d'acheter un logiciel compliqué pour comprendre le principe.&lt;/p&gt;

&lt;p&gt;Dans ce tuto, on va créer une mini facture très simple. Elle ne remplace pas un logiciel de comptabilité complet, surtout si vous avez des obligations légales précises. Mais elle montre comment produire un PDF propre, répétable, et facile à adapter.&lt;/p&gt;

&lt;h2&gt;
  
  
  L'outil utilisé
&lt;/h2&gt;

&lt;p&gt;On va utiliser &lt;code&gt;reportlab&lt;/code&gt;, une bibliothèque Python gratuite très connue pour créer des PDF. Si elle n'est pas installée, il faudra l'ajouter une fois sur votre ordinateur. Ensuite, le script pourra générer autant de PDF que vous voulez.&lt;/p&gt;

&lt;p&gt;Le principe est très simple : on crée une page, on écrit du texte à des positions précises, puis on sauvegarde le fichier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Le script Python
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;reportlab.lib.pagesizes&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;A4&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;reportlab.pdfgen&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;canvas&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;reportlab.lib.units&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;cm&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Boulangerie du Port&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;numero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;FAC-2026-001&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;lignes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Diagnostic ordinateur caisse&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;49.00&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Sauvegarde des fichiers&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;39.00&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Nettoyage logiciel&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;29.00&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;fichier_pdf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;facture-exemple.pdf&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Canvas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fichier_pdf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pagesize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;A4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;largeur&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hauteur&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;A4&lt;/span&gt;

&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setFont&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Helvetica-Bold&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drawString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;cm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hauteur&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;cm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Facture&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setFont&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Helvetica&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drawString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;cm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hauteur&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;cm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Numéro : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;numero&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drawString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;cm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hauteur&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;3.7&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;cm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Client : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;line&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;cm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hauteur&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;4.5&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;cm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;largeur&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;cm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hauteur&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;4.5&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;cm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hauteur&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;5.5&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;cm&lt;/span&gt;
&lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;quantite&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prix&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;lignes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;montant&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;quantite&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;prix&lt;/span&gt;
    &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;montant&lt;/span&gt;
    &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drawString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;cm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drawRightString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;cm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;quantite&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; x &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;prix&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; €&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drawRightString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;19&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;cm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;montant&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; €&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;cm&lt;/span&gt;

&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;line&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;cm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;largeur&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;cm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;cm&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setFont&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Helvetica-Bold&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drawRightString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;19&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;cm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Total : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; €&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setFont&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Helvetica&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drawString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;cm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;cm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Document généré automatiquement avec Python.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PDF créé : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;fichier_pdf&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Ce que fait le script
&lt;/h2&gt;

&lt;p&gt;La liste &lt;code&gt;lignes&lt;/code&gt; contient les prestations. Chaque ligne a trois informations : le texte, la quantité, et le prix unitaire. Python calcule le total tout seul. Si vous ajoutez une prestation, le montant final change automatiquement.&lt;/p&gt;

&lt;p&gt;Les coordonnées peuvent sembler étranges au début. Dans un PDF, on place les éléments sur une page, un peu comme sur une feuille avec une règle. &lt;code&gt;2 * cm&lt;/code&gt; signifie simplement « deux centimètres depuis le bord ». On n'a pas besoin de tout comprendre d'un coup : commencez par modifier les textes et les prix.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comment l'utiliser au quotidien
&lt;/h2&gt;

&lt;p&gt;Vous pouvez transformer ce script en modèle. Par exemple, un réparateur peut changer le nom du client et les prestations après chaque intervention. Une association peut générer un rapport mensuel. Un freelance peut produire un devis simple.&lt;/p&gt;

&lt;p&gt;Le vrai intérêt arrive quand les données viennent d'un fichier. Imaginez un tableau avec tous les clients du mois. Python pourrait lire chaque ligne et générer un PDF par client. Là, le gain de temps devient énorme.&lt;/p&gt;

&lt;h2&gt;
  
  
  Attention aux obligations légales
&lt;/h2&gt;

&lt;p&gt;Une facture réelle doit respecter des règles : identité de l'entreprise, numéro unique, dates, mentions, TVA selon votre situation, conditions de paiement, et parfois d'autres informations. Ce tuto ne donne pas un modèle légal complet. Il donne une base technique.&lt;/p&gt;

&lt;p&gt;Si vous voulez l'utiliser pour une vraie activité, vérifiez les mentions obligatoires avec une source officielle ou votre comptable. L'automatisation ne dispense pas d'être carré.&lt;/p&gt;

&lt;h2&gt;
  
  
  À retenir
&lt;/h2&gt;

&lt;p&gt;Créer un PDF avec Python, ce n'est pas réservé aux grosses entreprises. Pour des documents répétitifs, c'est même une excellente porte d'entrée dans l'automatisation. Vous commencez avec une facture simple, puis vous ajoutez petit à petit votre logo, vos couleurs, vos conditions, ou vos données clients.&lt;/p&gt;

&lt;p&gt;Le but n'est pas de faire joli dès le premier jour. Le but est d'arrêter de recopier les mêmes informations à la main.&lt;/p&gt;

</description>
      <category>python</category>
      <category>automation</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Trier et classer automatiquement ses photos et documents avec Python</title>
      <dc:creator>Dev du Sud</dc:creator>
      <pubDate>Wed, 21 Oct 2026 22:14:44 +0000</pubDate>
      <link>https://dev.to/devdusud/trier-et-classer-automatiquement-ses-photos-et-documents-avec-python-b9j</link>
      <guid>https://dev.to/devdusud/trier-et-classer-automatiquement-ses-photos-et-documents-avec-python-b9j</guid>
      <description>&lt;h2&gt;
  
  
  Le grand dossier en vrac
&lt;/h2&gt;

&lt;p&gt;Sur beaucoup d'ordinateurs, il existe un dossier qui fait peur. Il s'appelle souvent &lt;code&gt;Téléchargements&lt;/code&gt;, &lt;code&gt;Bureau&lt;/code&gt;, ou &lt;code&gt;À trier&lt;/code&gt;. Dedans, on trouve des photos, des PDF, des captures d'écran, des factures, des fichiers Word, des archives ZIP, parfois même des choses qu'on ne reconnaît plus.&lt;/p&gt;

&lt;p&gt;Ranger tout ça à la main prend du temps. Et comme ce n'est pas très amusant, on repousse. Résultat : le dossier grossit encore.&lt;/p&gt;

&lt;p&gt;Python peut aider à faire un premier tri automatique. L'idée n'est pas de deviner parfaitement le contenu de chaque document. L'idée est plus simple : classer les fichiers par famille grâce à leur extension. Les &lt;code&gt;.jpg&lt;/code&gt; vont dans &lt;code&gt;Photos&lt;/code&gt;, les &lt;code&gt;.pdf&lt;/code&gt; dans &lt;code&gt;PDF&lt;/code&gt;, les &lt;code&gt;.docx&lt;/code&gt; dans &lt;code&gt;Documents&lt;/code&gt;, et ainsi de suite.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pourquoi commencer par les extensions
&lt;/h2&gt;

&lt;p&gt;L'extension, c'est la fin du nom du fichier : &lt;code&gt;.jpg&lt;/code&gt;, &lt;code&gt;.pdf&lt;/code&gt;, &lt;code&gt;.xlsx&lt;/code&gt;, &lt;code&gt;.png&lt;/code&gt;. Ce n'est pas parfait, mais c'est déjà très utile. Pour un premier rangement, on n'a pas besoin d'intelligence artificielle. Une règle claire suffit.&lt;/p&gt;

&lt;p&gt;Avant de lancer le script sur votre vrai dossier &lt;code&gt;Téléchargements&lt;/code&gt;, copiez quelques fichiers dans un dossier de test. C'est une bonne habitude : on teste petit, puis on applique plus grand.&lt;/p&gt;

&lt;h2&gt;
  
  
  Le script Python
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;shutil&lt;/span&gt;

&lt;span class="n"&gt;DOSSIER_A_TRIER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a-trier&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;MODE_TEST&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="n"&gt;CATEGORIES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Photos&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.jpg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.jpeg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.png&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.gif&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.webp&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PDF&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.pdf&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Documents&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.doc&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.docx&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.odt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Tableurs&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.xls&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.xlsx&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Archives&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.zip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.rar&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.7z&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;trouver_categorie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;extension&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;categorie&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;extensions&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;CATEGORIES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;extension&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;categorie&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Autres&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;fichier&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;DOSSIER_A_TRIER&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;iterdir&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;fichier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_file&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;continue&lt;/span&gt;

    &lt;span class="n"&gt;categorie&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;trouver_categorie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fichier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;suffix&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="n"&gt;dossier_destination&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DOSSIER_A_TRIER&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;categorie&lt;/span&gt;
    &lt;span class="n"&gt;nouvelle_adresse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dossier_destination&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;fichier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;fichier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; -&amp;gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;categorie&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;MODE_TEST&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;dossier_destination&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exist_ok&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;shutil&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fichier&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nouvelle_adresse&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Comment utiliser ce script
&lt;/h2&gt;

&lt;p&gt;Créez un dossier &lt;code&gt;a-trier&lt;/code&gt;, mettez une dizaine de fichiers dedans, puis lancez le script. Au départ, &lt;code&gt;MODE_TEST&lt;/code&gt; est à &lt;code&gt;True&lt;/code&gt;. Le script affiche ce qu'il ferait, mais ne déplace rien. C'est parfait pour vérifier que les catégories vous conviennent.&lt;/p&gt;

&lt;p&gt;Quand le résultat affiché semble bon, passez &lt;code&gt;MODE_TEST&lt;/code&gt; à &lt;code&gt;False&lt;/code&gt;. Le script créera les dossiers nécessaires et déplacera les fichiers.&lt;/p&gt;

&lt;p&gt;Si vous voulez ajouter une catégorie, modifiez simplement le dictionnaire &lt;code&gt;CATEGORIES&lt;/code&gt;. Par exemple, vous pouvez créer une catégorie &lt;code&gt;Images boutique&lt;/code&gt; pour les &lt;code&gt;.jpg&lt;/code&gt; et &lt;code&gt;.png&lt;/code&gt;, ou une catégorie &lt;code&gt;Compta&lt;/code&gt; pour certains fichiers si vous adaptez ensuite la règle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Les limites à connaître
&lt;/h2&gt;

&lt;p&gt;Ce script ne lit pas le contenu des documents. Un PDF de facture et un PDF de menu restaurant iront tous les deux dans &lt;code&gt;PDF&lt;/code&gt;. Pour faire mieux, il faudrait analyser le texte, les dates, ou les noms de fichiers. C'est possible, mais ce serait une étape suivante.&lt;/p&gt;

&lt;p&gt;Autre limite : si un fichier du même nom existe déjà dans le dossier de destination, le déplacement peut poser problème. Pour un usage sérieux, on peut ajouter une règle qui renomme automatiquement le fichier en ajoutant un numéro. Pour débuter, gardons le script lisible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Une bonne méthode de rangement
&lt;/h2&gt;

&lt;p&gt;L'automatisation ne remplace pas une bonne logique. Avant de trier, demandez-vous quelles catégories vous voulez vraiment. Trop de dossiers, c'est aussi pénible que pas assez. Pour beaucoup de personnes, cinq ou six familles suffisent : Photos, PDF, Documents, Tableurs, Archives, Autres.&lt;/p&gt;

&lt;p&gt;Ensuite, lancez ce script une fois par semaine. Votre dossier &lt;code&gt;Téléchargements&lt;/code&gt; ne deviendra plus une décharge numérique.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pourquoi c'est utile pour un non-développeur
&lt;/h2&gt;

&lt;p&gt;Ce type de script donne une sensation très agréable : l'ordinateur fait enfin ce qu'on lui demande. Pas besoin de comprendre des concepts compliqués. On écrit une règle simple, puis Python l'applique sans se lasser.&lt;/p&gt;

&lt;p&gt;Pour une petite entreprise, ce rangement peut éviter de perdre des factures, des photos produits ou des documents clients. Pour un particulier, ça rend juste l'ordinateur plus respirable.&lt;/p&gt;

&lt;h2&gt;
  
  
  À retenir
&lt;/h2&gt;

&lt;p&gt;Un bon tri automatique commence petit. Une copie, quelques fichiers, un mode test, puis seulement après le vrai dossier. Avec cette méthode, vous avancez sans stress et vous gardez le contrôle.&lt;/p&gt;

</description>
      <category>python</category>
      <category>automation</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Scraper une page web pour récupérer des infos en restant poli</title>
      <dc:creator>Dev du Sud</dc:creator>
      <pubDate>Wed, 21 Oct 2026 21:18:58 +0000</pubDate>
      <link>https://dev.to/devdusud/scraper-une-page-web-pour-recuperer-des-infos-en-restant-poli-4akp</link>
      <guid>https://dev.to/devdusud/scraper-une-page-web-pour-recuperer-des-infos-en-restant-poli-4akp</guid>
      <description>&lt;h2&gt;
  
  
  Scraper, ça veut dire quoi ?
&lt;/h2&gt;

&lt;p&gt;Scraper une page web, c'est demander à Python de lire une page internet et d'en extraire une information. Par exemple : le titre d'un article, le prix affiché sur une page produit, une liste d'horaires, ou les liens présents dans une page.&lt;/p&gt;

&lt;p&gt;C'est pratique, mais ce n'est pas une excuse pour aspirer tout un site comme un sauvage. Derrière un site, il y a un serveur, une personne, une entreprise, parfois un petit commerçant. Un script mal réglé peut envoyer trop de requêtes et gêner le site.&lt;/p&gt;

&lt;p&gt;Dans ce tuto, on va faire un exemple simple et poli : télécharger une seule page, annoncer qui on est avec un &lt;code&gt;User-Agent&lt;/code&gt;, attendre entre les demandes si on en fait plusieurs, et ne pas contourner les protections.&lt;/p&gt;

&lt;h2&gt;
  
  
  Les règles de base
&lt;/h2&gt;

&lt;p&gt;Avant de scraper, regardez si le site propose une API ou un fichier export. C'est souvent plus propre. Lisez aussi les conditions d'utilisation si les données sont sensibles ou commerciales.&lt;/p&gt;

&lt;p&gt;Ne récupérez pas de données personnelles sans raison claire. Ne contournez pas un login, un paywall, un captcha ou une interdiction technique. Et si un site dit non dans son fichier &lt;code&gt;robots.txt&lt;/code&gt;, respectez ce signal, surtout pour un projet automatisé.&lt;/p&gt;

&lt;p&gt;Le scraping doit rester raisonnable : peu de pages, peu souvent, et avec un vrai besoin.&lt;/p&gt;

&lt;h2&gt;
  
  
  Le script Python
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;html.parser&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HTMLParser&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;urllib.request&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;urlopen&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sleep&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ExtracteurTitres&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HTMLParser&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;super&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dans_h2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;titres&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handle_starttag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;h2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dans_h2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handle_endtag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;h2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dans_h2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handle_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;texte&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dans_h2&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;texte&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;titres&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;texte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://example.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;requete&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User-Agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DevDuSudBot/1.0 contact: contact@example.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;urlopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requete&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;reponse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;reponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ignore&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;extracteur&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ExtracteurTitres&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;extracteur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;feed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;titre&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;extracteur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;titres&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;titre&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Ce que fait le script
&lt;/h2&gt;

&lt;p&gt;Le script télécharge une page, lit son HTML, puis récupère le texte placé dans les balises &lt;code&gt;h2&lt;/code&gt;. Sur certains sites, les titres sont dans des &lt;code&gt;h1&lt;/code&gt;, &lt;code&gt;h2&lt;/code&gt;, &lt;code&gt;h3&lt;/code&gt;, ou dans des blocs plus complexes. Il faudra donc adapter selon la page.&lt;/p&gt;

&lt;p&gt;Le &lt;code&gt;User-Agent&lt;/code&gt; est une phrase d'identité. Au lieu de se cacher, votre script explique qui il est. Pour un vrai projet, mettez une adresse de contact valable. Cela montre que vous n'essayez pas de vous faire passer pour un navigateur humain.&lt;/p&gt;

&lt;p&gt;Le &lt;code&gt;sleep(2)&lt;/code&gt; marque une pause. Ici, on ne fait qu'une page, donc il ne sert pas beaucoup. Mais si vous parcourez plusieurs pages, cette pause évite de taper trop vite sur le serveur.&lt;/p&gt;

&lt;h2&gt;
  
  
  Un exemple utile et raisonnable
&lt;/h2&gt;

&lt;p&gt;Imaginez un commerçant qui veut vérifier une fois par jour si ses horaires apparaissent correctement sur une page partenaire. Le script peut lire la page, chercher un texte, et alerter si l'information change. C'est un usage raisonnable.&lt;/p&gt;

&lt;p&gt;À l'inverse, aspirer tout un catalogue concurrent toutes les dix secondes serait agressif. Même si c'est techniquement possible, ce n'est pas une bonne idée.&lt;/p&gt;

&lt;h2&gt;
  
  
  Les limites du scraping
&lt;/h2&gt;

&lt;p&gt;Beaucoup de sites modernes chargent les informations avec JavaScript. Dans ce cas, le HTML reçu par Python peut être presque vide. Il faut alors utiliser d'autres outils, parfois plus lourds, ou chercher une API officielle.&lt;/p&gt;

&lt;p&gt;Autre limite : la structure d'une page peut changer. Si le site remplace ses &lt;code&gt;h2&lt;/code&gt; par autre chose, votre script ne trouvera plus rien. Un scraper doit donc être surveillé et corrigé de temps en temps.&lt;/p&gt;

&lt;h2&gt;
  
  
  À retenir
&lt;/h2&gt;

&lt;p&gt;Scraper, ce n'est pas voler ni spammer. C'est lire automatiquement une page publique, avec mesure et respect. La bonne attitude est simple : peu de requêtes, une identité claire, pas de contournement, pas de données sensibles inutiles.&lt;/p&gt;

&lt;p&gt;Python donne le pouvoir de récupérer de l'information. La partie importante, c'est de l'utiliser proprement.&lt;/p&gt;

</description>
      <category>python</category>
      <category>automation</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Une facture, un fichier HTML, zéro serveur : ce que j'ai appris en fabriquant mon outil de facturation</title>
      <dc:creator>Dev du Sud</dc:creator>
      <pubDate>Wed, 21 Oct 2026 18:51:25 +0000</pubDate>
      <link>https://dev.to/devdusud/une-facture-un-fichier-html-zero-serveur-ce-que-jai-appris-en-fabriquant-mon-outil-de-2alj</link>
      <guid>https://dev.to/devdusud/une-facture-un-fichier-html-zero-serveur-ce-que-jai-appris-en-fabriquant-mon-outil-de-2alj</guid>
      <description>&lt;p&gt;Je ne suis pas développeur. Je suis technicien IT, et je passe mes journées à réparer&lt;br&gt;
les machines des autres. Comme beaucoup d'indépendants, je facturais mal : un tableur,&lt;br&gt;
des numéros qui se perdent, des mentions légales que je recopiais d'une vieille facture.&lt;/p&gt;

&lt;p&gt;Je voulais un outil de facturation qui :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fonctionne sans connexion (je travaille souvent dans des locaux sans wifi correct) ;&lt;/li&gt;
&lt;li&gt;ne m'oblige pas à créer un compte chez quelqu'un ;&lt;/li&gt;
&lt;li&gt;ne m'abonne pas à 12 € par mois pour sortir deux factures ;&lt;/li&gt;
&lt;li&gt;tienne sur une clé USB, parce que je change souvent de machine.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;La solution la plus simple que j'ai trouvée : une seule page HTML, du JavaScript,&lt;br&gt;
et le stockage local du navigateur. Pas de serveur, pas de base de données, pas de&lt;br&gt;
déploiement. On ouvre le fichier, on facture, on ferme. Les données ne quittent pas&lt;br&gt;
la machine.&lt;/p&gt;

&lt;p&gt;Trois choses que j'ai apprises en le construisant :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Le stockage local est plus fragile qu'on croit.&lt;/strong&gt; Un nettoyage de navigateur, et
tout disparaît. J'ai donc ajouté un export des données : ce n'est pas glamour,
mais c'est la fonctionnalité la plus importante de l'outil.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Les mentions légales sont la vraie difficulté.&lt;/strong&gt; Le code, c'est une journée.
Savoir ce qu'une facture de micro-entreprise doit contenir, c'est le reste du travail.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Un outil qu'on n'ose pas ouvrir ne sert à rien.&lt;/strong&gt; J'ai supprimé la moitié des
champs que je trouvais « utiles ». Une facture doit se faire en deux minutes,
pas en dix.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Je l'ai ensuite mis en PDF avec un mode d'emploi, parce que plusieurs collègues&lt;br&gt;
artisans m'ont demandé le fichier. C'est ici, 19,90 €, paiement unique :&lt;br&gt;
&lt;a href="https://revedebiz.gumroad.com/l/ngseyv" rel="noopener noreferrer"&gt;https://revedebiz.gumroad.com/l/ngseyv&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Si vous bricolez le même genre d'outil, je suis preneur de vos retours — surtout&lt;br&gt;
sur la partie sauvegarde, c'est là que je suis le moins sûr de moi.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>html</category>
      <category>freelance</category>
      <category>productivity</category>
    </item>
    <item>
      <title>3 erreurs qui font fuir tes clients</title>
      <dc:creator>Dev du Sud</dc:creator>
      <pubDate>Sun, 18 Oct 2026 15:51:26 +0000</pubDate>
      <link>https://dev.to/devdusud/3-erreurs-qui-font-fuir-tes-clients-54cb</link>
      <guid>https://dev.to/devdusud/3-erreurs-qui-font-fuir-tes-clients-54cb</guid>
      <description>&lt;p&gt;3 erreurs qui te coûtent des clients 💸&lt;/p&gt;

&lt;p&gt;Ton site te vend... ou te dessert. Tu sais lequel ?&lt;/p&gt;

&lt;h1&gt;
  
  
  siteweb #clients #conversion #entrepreneur #conseils
&lt;/h1&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/W_-m5lT_K5U" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>siteweb</category>
      <category>clients</category>
      <category>conversion</category>
      <category>entrepreneur</category>
    </item>
    <item>
      <title>Publier un site en 5 minutes</title>
      <dc:creator>Dev du Sud</dc:creator>
      <pubDate>Sun, 18 Oct 2026 15:50:36 +0000</pubDate>
      <link>https://dev.to/devdusud/publier-un-site-en-5-minutes-1m4n</link>
      <guid>https://dev.to/devdusud/publier-un-site-en-5-minutes-1m4n</guid>
      <description>&lt;p&gt;Un site en ligne en 5 minutes chrono ⚡&lt;/p&gt;

&lt;p&gt;Pas besoin d'une semaine, ni de 200€ de budget. Juste une méthode. Sauvegarde, la démo arrive.&lt;/p&gt;

&lt;h1&gt;
  
  
  siteweb #créationsite #devweb #hébergement #tuto
&lt;/h1&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/4TiKT64vO5U" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>siteweb</category>
      <category>créationsite</category>
      <category>devweb</category>
      <category>hébergement</category>
    </item>
    <item>
      <title>Ton travail ou ton IA ?</title>
      <dc:creator>Dev du Sud</dc:creator>
      <pubDate>Sun, 18 Oct 2026 15:50:35 +0000</pubDate>
      <link>https://dev.to/devdusud/ton-travail-ou-ton-ia--3j29</link>
      <guid>https://dev.to/devdusud/ton-travail-ou-ton-ia--3j29</guid>
      <description>&lt;p&gt;Ton travail, ou celui de ton IA ? 🤖&lt;/p&gt;

&lt;p&gt;La plupart des gens perdent 2h par jour sur des trucs qu'un agent ferait en 2 minutes. En 2026, ne pas automatiser, c'est choisir de perdre du temps.&lt;/p&gt;

&lt;h1&gt;
  
  
  IA #automatisation #agentIA #productivité #dev
&lt;/h1&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/iQFepR64EnE" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>ia</category>
      <category>automatisation</category>
      <category>agentia</category>
      <category>productivité</category>
    </item>
    <item>
      <title>Envoyer un email automatique pour rappeler les rendez-vous d'un commerçant</title>
      <dc:creator>Dev du Sud</dc:creator>
      <pubDate>Thu, 15 Oct 2026 07:34:10 +0000</pubDate>
      <link>https://dev.to/devdusud/envoyer-un-email-automatique-pour-rappeler-les-rendez-vous-dun-commercant-3aco</link>
      <guid>https://dev.to/devdusud/envoyer-un-email-automatique-pour-rappeler-les-rendez-vous-dun-commercant-3aco</guid>
      <description>&lt;h2&gt;
  
  
  Le besoin très concret
&lt;/h2&gt;

&lt;p&gt;Un salon de coiffure, un garage, une sophrologue, un réparateur informatique ou un cabinet de bien-être ont tous le même problème : les rendez-vous oubliés. Une personne ne vient pas, le créneau est perdu, et personne n'est content.&lt;/p&gt;

&lt;p&gt;On peut payer un gros logiciel pour gérer ça. Mais pour comprendre le principe, un petit script Python suffit. Il lit une liste de rendez-vous, repère ceux qui arrivent bientôt, puis envoie un email de rappel.&lt;/p&gt;

&lt;p&gt;Le but n'est pas de remplacer un vrai outil métier complet. Le but est de voir comment automatiser une tâche simple : « demain, pensez à votre rendez-vous ».&lt;/p&gt;

&lt;h2&gt;
  
  
  Ce qu'on va faire
&lt;/h2&gt;

&lt;p&gt;On va imaginer un fichier de rendez-vous dans le script, pour rester simple. Dans la vraie vie, cette liste pourrait venir d'un fichier CSV, d'un agenda Google, ou d'un logiciel. Chaque rendez-vous contient un nom, une adresse email, une date et une heure.&lt;/p&gt;

&lt;p&gt;Le script vérifie les rendez-vous prévus demain. S'il en trouve un, il prépare un message et l'envoie avec une boîte email classique.&lt;/p&gt;

&lt;p&gt;Important : ne mettez jamais votre mot de passe directement dans le code. On utilise des variables d'environnement. C'est une façon plus propre de dire à Python : « va chercher le mot de passe ailleurs ».&lt;/p&gt;

&lt;h2&gt;
  
  
  Le script Python
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;smtplib&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timedelta&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;email.message&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;EmailMessage&lt;/span&gt;

&lt;span class="n"&gt;SMTP_SERVER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;smtp.gmail.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;SMTP_PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;587&lt;/span&gt;
&lt;span class="n"&gt;EMAIL_EXPEDITEUR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;EMAIL_EXPEDITEUR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;MOT_DE_PASSE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;EMAIL_MOT_DE_PASSE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;rendez_vous&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nom&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Nadia&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nadia@example.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2026-10-12&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;heure&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;14:30&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nom&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Karim&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;karim@example.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2026-10-15&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;heure&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;09:00&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;demain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;today&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;days&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;isoformat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;smtplib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SMTP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SMTP_SERVER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SMTP_PORT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;serveur&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;serveur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;starttls&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;serveur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EMAIL_EXPEDITEUR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MOT_DE_PASSE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;rdv&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;rendez_vous&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;rdv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;demain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;

        &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;EmailMessage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;From&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EMAIL_EXPEDITEUR&lt;/span&gt;
        &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;To&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rdv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Subject&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Rappel de votre rendez-vous&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bonjour &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;rdv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;nom&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;,

&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Petit rappel : votre rendez-vous est prévu demain à &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;rdv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;heure&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.
&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Si vous avez un empêchement, merci de nous prévenir.

&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bonne journée !&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;serveur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Rappel envoyé à &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;rdv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;nom&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Comment l'adapter simplement
&lt;/h2&gt;

&lt;p&gt;La partie &lt;code&gt;rendez_vous&lt;/code&gt; est votre mini agenda. Pour tester, remplacez les emails d'exemple par une adresse à vous. Ne testez jamais directement sur de vrais clients au premier essai. Envoyez-vous le message, vérifiez le texte, puis seulement après utilisez une vraie liste.&lt;/p&gt;

&lt;p&gt;Pour Gmail, il faut souvent créer un mot de passe d'application. Ce n'est pas votre mot de passe principal. C'est un mot de passe spécial pour les scripts. D'autres fournisseurs email ont un système équivalent.&lt;/p&gt;

&lt;p&gt;Les variables &lt;code&gt;EMAIL_EXPEDITEUR&lt;/code&gt; et &lt;code&gt;EMAIL_MOT_DE_PASSE&lt;/code&gt; se configurent dans votre système. Sur Linux ou Mac, on peut les définir dans le terminal. Sur Windows, on peut les ajouter dans les variables d'environnement. L'idée est toujours la même : le code ne doit pas afficher le secret.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ce qu'il ne faut pas faire
&lt;/h2&gt;

&lt;p&gt;N'envoyez pas 500 emails d'un coup depuis une boîte personnelle. Les fournisseurs peuvent croire à du spam. Commencez petit, avec quelques messages, et gardez un ton utile. Un rappel de rendez-vous, c'est normal. Une pub répétée, c'est autre chose.&lt;/p&gt;

&lt;p&gt;Ajoutez toujours une phrase humaine : comment annuler, comment prévenir, ou à quel numéro appeler. L'automatisation doit aider la relation client, pas donner l'impression qu'un robot froid parle à votre place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pourquoi c'est puissant
&lt;/h2&gt;

&lt;p&gt;Un email automatique, ce n'est pas magique. C'est juste une règle répétée au bon moment. Mais pour un petit commerce, ça peut éviter des oublis, libérer du temps, et donner une image plus organisée.&lt;/p&gt;

&lt;p&gt;Python devient ici un assistant discret. Il ne vend rien, il ne remplace pas le contact humain. Il pense juste à envoyer le rappel quand vous êtes occupé à autre chose.&lt;/p&gt;

&lt;h2&gt;
  
  
  À retenir
&lt;/h2&gt;

&lt;p&gt;Commencez avec votre propre adresse email, testez, corrigez le message, puis seulement après utilisez de vrais rendez-vous. Un bon script professionnel est d'abord un script prudent.&lt;/p&gt;

</description>
      <category>python</category>
      <category>automation</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Renommer 500 fichiers en 2 secondes avec Python</title>
      <dc:creator>Dev du Sud</dc:creator>
      <pubDate>Wed, 14 Oct 2026 07:01:02 +0000</pubDate>
      <link>https://dev.to/devdusud/renommer-500-fichiers-en-2-secondes-avec-python-1757</link>
      <guid>https://dev.to/devdusud/renommer-500-fichiers-en-2-secondes-avec-python-1757</guid>
      <description>&lt;h2&gt;
  
  
  Le problème du dossier qui déborde
&lt;/h2&gt;

&lt;p&gt;Vous avez peut-être déjà vécu ça : un dossier rempli de photos, de factures scannées ou de fichiers téléchargés avec des noms impossibles. Des &lt;code&gt;IMG_4891.jpg&lt;/code&gt;, &lt;code&gt;scan0007.pdf&lt;/code&gt;, &lt;code&gt;nouveau_document_final_vrai_final.pdf&lt;/code&gt;. Quand il y en a 10, on peut s'en sortir à la main. Quand il y en a 500, c'est une punition.&lt;/p&gt;

&lt;p&gt;L'idée de ce tuto est simple : demander à Python de parcourir un dossier et de renommer chaque fichier proprement. Pas besoin d'être développeur. On va préparer un petit script, le tester en mode prudent, puis le lancer pour de vrai.&lt;/p&gt;

&lt;p&gt;Exemple concret : un commerçant reçoit chaque semaine des photos produits. Au lieu de garder &lt;code&gt;DSC_001.jpg&lt;/code&gt;, il veut obtenir &lt;code&gt;produit-001.jpg&lt;/code&gt;, &lt;code&gt;produit-002.jpg&lt;/code&gt;, etc. C'est plus lisible, plus facile à envoyer, et beaucoup moins stressant.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ce qu'il faut préparer
&lt;/h2&gt;

&lt;p&gt;Avant de toucher aux fichiers, faites une copie du dossier. C'est la règle numéro 1. Un script peut aller très vite, donc on teste toujours sur une copie avant de l'utiliser sur les vrais documents.&lt;/p&gt;

&lt;p&gt;Créez ensuite un dossier simple, par exemple &lt;code&gt;a-renommer&lt;/code&gt;, et mettez quelques fichiers dedans. Le script ci-dessous va seulement renommer les fichiers, pas les sous-dossiers. C'est volontaire : pour débuter, on reste simple.&lt;/p&gt;

&lt;h2&gt;
  
  
  Le script Python
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;

&lt;span class="n"&gt;DOSSIER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a-renommer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;PREFIXE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;produit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;MODE_TEST&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;  &lt;span class="c1"&gt;# Passez à False quand tout vous semble bon
&lt;/span&gt;
&lt;span class="n"&gt;fichiers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;DOSSIER&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;iterdir&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_file&lt;/span&gt;&lt;span class="p"&gt;()])&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;numero&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fichier&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fichiers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;extension&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fichier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;suffix&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;nouveau_nom&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;PREFIXE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;numero&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;03&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="si"&gt;}{&lt;/span&gt;&lt;span class="n"&gt;extension&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;nouvelle_adresse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DOSSIER&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;nouveau_nom&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;fichier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;  -&amp;gt;  &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;nouveau_nom&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;MODE_TEST&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fichier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rename&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nouvelle_adresse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Terminé : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fichiers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; fichier(s) traité(s).&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Comment le lire sans paniquer
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Path("a-renommer")&lt;/code&gt; indique le dossier à traiter. Si votre dossier s'appelle autrement, changez seulement cette ligne. &lt;code&gt;PREFIXE&lt;/code&gt; est le début du nouveau nom. Ici, tous les fichiers deviendront &lt;code&gt;produit-001&lt;/code&gt;, &lt;code&gt;produit-002&lt;/code&gt;, et ainsi de suite.&lt;/p&gt;

&lt;p&gt;La ligne la plus importante est &lt;code&gt;MODE_TEST = True&lt;/code&gt;. Tant qu'elle reste à &lt;code&gt;True&lt;/code&gt;, Python affiche ce qu'il ferait, mais ne renomme rien. C'est comme une répétition générale. Vous pouvez vérifier tranquillement que le résultat vous plaît.&lt;/p&gt;

&lt;p&gt;Quand vous êtes sûr, remplacez &lt;code&gt;True&lt;/code&gt; par &lt;code&gt;False&lt;/code&gt;, relancez le script, et les fichiers seront renommés.&lt;/p&gt;

&lt;h2&gt;
  
  
  Les petits pièges à connaître
&lt;/h2&gt;

&lt;p&gt;Premier piège : deux fichiers ne peuvent pas avoir exactement le même nom dans le même dossier. Notre script évite ça grâce au numéro automatique. Deuxième piège : l'ordre. Ici, on utilise &lt;code&gt;sorted&lt;/code&gt;, donc Python trie les fichiers par nom avant de les renommer. Si vous voulez un ordre par date de création ou de modification, c'est possible, mais on garde ça pour un tuto plus avancé.&lt;/p&gt;

&lt;p&gt;Troisième piège : les extensions. Le script garde &lt;code&gt;.jpg&lt;/code&gt;, &lt;code&gt;.pdf&lt;/code&gt;, &lt;code&gt;.png&lt;/code&gt; ou autre, en minuscules. C'est pratique pour éviter les mélanges entre &lt;code&gt;.JPG&lt;/code&gt; et &lt;code&gt;.jpg&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pourquoi c'est utile dans la vraie vie
&lt;/h2&gt;

&lt;p&gt;Ce petit script peut servir à un photographe, une boutique en ligne, une association, un artisan, ou juste à quelqu'un qui veut ranger son ordinateur. Le vrai gain n'est pas seulement de gagner deux minutes. C'est surtout d'éviter les erreurs répétitives.&lt;/p&gt;

&lt;p&gt;Renommer 500 fichiers à la main, c'est fatigant. Et quand on est fatigué, on se trompe. Python, lui, répète la même règle sans râler. Vous décidez de la règle, il applique.&lt;/p&gt;

&lt;h2&gt;
  
  
  À retenir
&lt;/h2&gt;

&lt;p&gt;Un bon automatisme ne doit pas être compliqué. Il doit être clair, testable, et réversible si possible. Ici, le mode test vous protège. La copie du dossier vous protège aussi. Avec ces deux habitudes, vous pouvez commencer à automatiser des tâches simples sans peur.&lt;/p&gt;

&lt;p&gt;C'est exactement l'esprit Dev du Sud : utiliser Python comme un petit assistant de bureau, pas comme un truc réservé aux ingénieurs.&lt;/p&gt;

</description>
      <category>python</category>
      <category>automation</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Renommer 500 fichiers en 2 secondes avec Python</title>
      <dc:creator>Dev du Sud</dc:creator>
      <pubDate>Wed, 14 Oct 2026 06:41:42 +0000</pubDate>
      <link>https://dev.to/devdusud/renommer-500-fichiers-en-2-secondes-avec-python-28jh</link>
      <guid>https://dev.to/devdusud/renommer-500-fichiers-en-2-secondes-avec-python-28jh</guid>
      <description>&lt;h2&gt;
  
  
  Le problème du dossier qui déborde
&lt;/h2&gt;

&lt;p&gt;Vous avez peut-être déjà vécu ça : un dossier rempli de photos, de factures scannées ou de fichiers téléchargés avec des noms impossibles. Des &lt;code&gt;IMG_4891.jpg&lt;/code&gt;, &lt;code&gt;scan0007.pdf&lt;/code&gt;, &lt;code&gt;nouveau_document_final_vrai_final.pdf&lt;/code&gt;. Quand il y en a 10, on peut s'en sortir à la main. Quand il y en a 500, c'est une punition.&lt;/p&gt;

&lt;p&gt;L'idée de ce tuto est simple : demander à Python de parcourir un dossier et de renommer chaque fichier proprement. Pas besoin d'être développeur. On va préparer un petit script, le tester en mode prudent, puis le lancer pour de vrai.&lt;/p&gt;

&lt;p&gt;Exemple concret : un commerçant reçoit chaque semaine des photos produits. Au lieu de garder &lt;code&gt;DSC_001.jpg&lt;/code&gt;, il veut obtenir &lt;code&gt;produit-001.jpg&lt;/code&gt;, &lt;code&gt;produit-002.jpg&lt;/code&gt;, etc. C'est plus lisible, plus facile à envoyer, et beaucoup moins stressant.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ce qu'il faut préparer
&lt;/h2&gt;

&lt;p&gt;Avant de toucher aux fichiers, faites une copie du dossier. C'est la règle numéro 1. Un script peut aller très vite, donc on teste toujours sur une copie avant de l'utiliser sur les vrais documents.&lt;/p&gt;

&lt;p&gt;Créez ensuite un dossier simple, par exemple &lt;code&gt;a-renommer&lt;/code&gt;, et mettez quelques fichiers dedans. Le script ci-dessous va seulement renommer les fichiers, pas les sous-dossiers. C'est volontaire : pour débuter, on reste simple.&lt;/p&gt;

&lt;h2&gt;
  
  
  Le script Python
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;

&lt;span class="n"&gt;DOSSIER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a-renommer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;PREFIXE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;produit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;MODE_TEST&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;  &lt;span class="c1"&gt;# Passez à False quand tout vous semble bon
&lt;/span&gt;
&lt;span class="n"&gt;fichiers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;DOSSIER&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;iterdir&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_file&lt;/span&gt;&lt;span class="p"&gt;()])&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;numero&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fichier&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fichiers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;extension&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fichier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;suffix&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;nouveau_nom&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;PREFIXE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;numero&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;03&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="si"&gt;}{&lt;/span&gt;&lt;span class="n"&gt;extension&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;nouvelle_adresse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DOSSIER&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;nouveau_nom&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;fichier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;  -&amp;gt;  &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;nouveau_nom&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;MODE_TEST&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fichier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rename&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nouvelle_adresse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Terminé : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fichiers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; fichier(s) traité(s).&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Comment le lire sans paniquer
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Path("a-renommer")&lt;/code&gt; indique le dossier à traiter. Si votre dossier s'appelle autrement, changez seulement cette ligne. &lt;code&gt;PREFIXE&lt;/code&gt; est le début du nouveau nom. Ici, tous les fichiers deviendront &lt;code&gt;produit-001&lt;/code&gt;, &lt;code&gt;produit-002&lt;/code&gt;, et ainsi de suite.&lt;/p&gt;

&lt;p&gt;La ligne la plus importante est &lt;code&gt;MODE_TEST = True&lt;/code&gt;. Tant qu'elle reste à &lt;code&gt;True&lt;/code&gt;, Python affiche ce qu'il ferait, mais ne renomme rien. C'est comme une répétition générale. Vous pouvez vérifier tranquillement que le résultat vous plaît.&lt;/p&gt;

&lt;p&gt;Quand vous êtes sûr, remplacez &lt;code&gt;True&lt;/code&gt; par &lt;code&gt;False&lt;/code&gt;, relancez le script, et les fichiers seront renommés.&lt;/p&gt;

&lt;h2&gt;
  
  
  Les petits pièges à connaître
&lt;/h2&gt;

&lt;p&gt;Premier piège : deux fichiers ne peuvent pas avoir exactement le même nom dans le même dossier. Notre script évite ça grâce au numéro automatique. Deuxième piège : l'ordre. Ici, on utilise &lt;code&gt;sorted&lt;/code&gt;, donc Python trie les fichiers par nom avant de les renommer. Si vous voulez un ordre par date de création ou de modification, c'est possible, mais on garde ça pour un tuto plus avancé.&lt;/p&gt;

&lt;p&gt;Troisième piège : les extensions. Le script garde &lt;code&gt;.jpg&lt;/code&gt;, &lt;code&gt;.pdf&lt;/code&gt;, &lt;code&gt;.png&lt;/code&gt; ou autre, en minuscules. C'est pratique pour éviter les mélanges entre &lt;code&gt;.JPG&lt;/code&gt; et &lt;code&gt;.jpg&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pourquoi c'est utile dans la vraie vie
&lt;/h2&gt;

&lt;p&gt;Ce petit script peut servir à un photographe, une boutique en ligne, une association, un artisan, ou juste à quelqu'un qui veut ranger son ordinateur. Le vrai gain n'est pas seulement de gagner deux minutes. C'est surtout d'éviter les erreurs répétitives.&lt;/p&gt;

&lt;p&gt;Renommer 500 fichiers à la main, c'est fatigant. Et quand on est fatigué, on se trompe. Python, lui, répète la même règle sans râler. Vous décidez de la règle, il applique.&lt;/p&gt;

&lt;h2&gt;
  
  
  À retenir
&lt;/h2&gt;

&lt;p&gt;Un bon automatisme ne doit pas être compliqué. Il doit être clair, testable, et réversible si possible. Ici, le mode test vous protège. La copie du dossier vous protège aussi. Avec ces deux habitudes, vous pouvez commencer à automatiser des tâches simples sans peur.&lt;/p&gt;

&lt;p&gt;C'est exactement l'esprit Dev du Sud : utiliser Python comme un petit assistant de bureau, pas comme un truc réservé aux ingénieurs.&lt;/p&gt;

</description>
      <category>python</category>
      <category>automation</category>
      <category>productivity</category>
    </item>
    <item>
      <title>J'ai publié 8 livres et guides sans dépenser un seul euro : le pipeline complet</title>
      <dc:creator>Dev du Sud</dc:creator>
      <pubDate>Sun, 04 Oct 2026 07:00:24 +0000</pubDate>
      <link>https://dev.to/devdusud/jai-publie-8-livres-et-guides-sans-depenser-un-seul-euro-le-pipeline-complet-295m</link>
      <guid>https://dev.to/devdusud/jai-publie-8-livres-et-guides-sans-depenser-un-seul-euro-le-pipeline-complet-295m</guid>
      <description>&lt;p&gt;Il y a trois semaines, je n'avais aucun produit en ligne. Aujourd'hui, huit guides sont en vente sur ma boutique, et une nouvelle sortie est prévue chaque lundi.&lt;/p&gt;

&lt;p&gt;Le plus intéressant n'est pas le contenu. C'est le pipeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Le principe : une usine, pas des coups de génie
&lt;/h2&gt;

&lt;p&gt;Chaque livre suit le même chemin :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Un thème est choisi dans une liste (productivité, IA, freelance, organisation…)&lt;/li&gt;
&lt;li&gt;Le contenu est rédigé en markdown&lt;/li&gt;
&lt;li&gt;Un script Python convertit le markdown en EPUB compatible Amazon KDP&lt;/li&gt;
&lt;li&gt;Le même contenu devient un PDF propre pour la vente directe&lt;/li&gt;
&lt;li&gt;L'API de la boutique crée le produit, téléverse le fichier, met en vente&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;La partie clé : les étapes 3 à 5 tournent toutes seules.&lt;/p&gt;

&lt;h2&gt;
  
  
  Le script qui fabrique les livres
&lt;/h2&gt;

&lt;p&gt;La conversion markdown vers EPUB tient en un fichier : un template XHTML, une table des matières générée, les métadonnées (titre, auteur, couverture). Rien de magique — un EPUB est un ZIP avec des fichiers structurés dedans.&lt;/p&gt;

&lt;p&gt;La seule chose à faire pour ajouter un livre : écrire le contenu et ajouter une entrée dans la liste des guides. Le script fait le reste.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pourquoi deux formats
&lt;/h2&gt;

&lt;p&gt;L'EPUB part vers Amazon KDP (lecteurs liseuses). Le PDF part vers la vente directe (lecteurs ordinateur). Le même contenu, deux canaux, zéro coût supplémentaire.&lt;/p&gt;

&lt;h2&gt;
  
  
  Le calendrier qui force la régularité
&lt;/h2&gt;

&lt;p&gt;Une tâche planifiée tourne chaque lundi matin. Elle choisit le prochain thème, génère le guide, et le met en vente. Je me réveille avec un nouveau produit en ligne.&lt;/p&gt;

&lt;p&gt;La leçon principale : la régularité bat le génie. Un petit guide utile par semaine vaut mieux qu'un chef-d'œuvre par an.&lt;/p&gt;

&lt;h2&gt;
  
  
  Le point important
&lt;/h2&gt;

&lt;p&gt;Tout est gratuit : les outils de conversion sont open source, la boutique ne prend qu'une commission sur les ventes, et l'hébergement des fichiers est inclus.&lt;/p&gt;

&lt;p&gt;Si vous avez une compétence que vous pouvez mettre en mots, vous pouvez monter le même système ce week-end.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Je documente mes automatisations maison sur &lt;a href="https://dev.to/devdusud"&gt;Dev du Sud&lt;/a&gt;. Si vous voulez voir le résultat du pipeline, c'est par là.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>productivity</category>
      <category>sideprojects</category>
    </item>
    <item>
      <title>The 10 Best Headphones in 2026</title>
      <dc:creator>Dev du Sud</dc:creator>
      <pubDate>Sun, 04 Oct 2026 06:40:23 +0000</pubDate>
      <link>https://dev.to/devdusud/the-10-best-headphones-in-2026-3bgf</link>
      <guid>https://dev.to/devdusud/the-10-best-headphones-in-2026-3bgf</guid>
      <description>&lt;p&gt;Music, focus or gaming: the 10 headphones truly worth your money this year.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://ludo1377.github.io/devdusud-guides/en/casques-audio/" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;ludo1377.github.io&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Sony WH-1000XM5&lt;/strong&gt; — Reference noise cancelling, exceptional comfort, 30 h battery. (ANC, 30 h, BT 5.2, ~$330)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anker Soundcore Life Q30&lt;/strong&gt; — Surprising ANC for the price, warm sound, very comfortable. (ANC, 40 h, ~$65)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SteelSeries Arctis Nova 7&lt;/strong&gt; — Dual wireless, clear mic, 38 h battery. (2.4 GHz + BT, 38 h, ~$175)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JBL Endurance Peak 3&lt;/strong&gt; — Earbuds that stay put, water and sweat resistant. (IP68, 40 h with case, ~$85)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apple AirPods Max&lt;/strong&gt; — Premium finish, spatial audio, ideal for the Apple ecosystem. (Spatial Audio, 20 h, ~$520)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;the Sony WH-1000XM5 remains the reference. On a budget, the Soundcore Q30 is unbeatable.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Article from our full guide: &lt;a href="https://ludo1377.github.io/devdusud-guides/en/casques-audio/" rel="noopener noreferrer"&gt;see the detailed comparison&lt;/a&gt;. Affiliate links disclosed — independent recommendations.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>buyingguide</category>
      <category>top10</category>
      <category>comparison</category>
    </item>
  </channel>
</rss>
