Des robots pour visiteurs

Quand je lis les journaux de mon serveur Web, j'ai l'impression que la plupart des visiteurs sont des robots.

La part des visiteurs qui s'identifient comme des robots via leur user agent est passée de moins de 30 % début 2024 à 40 % en décembre.

L'entraînement des modèles d'IA générative tels que les LLM nécessite un corpus toujours plus grand de données. Les entreprises du secteur ont donc développé des programmes qui parcourent le Web pour enregistrer le contenu des sites visités. Aux visiteurs de longue date que sont Googlebot et Bingbot se sont ajoutés GPTBot, ClaudeBot, Amazonbot, et bien d'autres.

Comment évaluer la part des robots parmi les visiteurs à partir des journaux ?

Les serveurs Web comme Apache enregistrent des informations sur les requêtes HTTP traitées dans un fichier journal des accès. Parmi ces informations figure l'en-tête user agent de la requête HTTP. Il s'agit d'une chaîne de caractère qui identifie le navigateur Web.

Le user agent des robots d'indexation contient en général les termes bot, crawler ou spider. Toutefois, un robot peut prétendre être un banal navigateur Web en usurpant son user agent.

Je suggère d'utiliser le logiciel libre Angle-grinder pour analyser le fichier journal des accès d'Apache et estimer le ratio des requêtes valides envoyées par des robots.

$ agrind -f a.log "* | apache | where status == 200 | if(contains(toLowerCase(contentlength), 'bot'), 1, 0) as bot_req | avg(bot_req) as bot_req_ratio"
bot_req_ratio
---------------------
0.40

Les pipelines, séparés par le caractère |, sont composés ainsi :

  1. Toutes les entrées du fichier journal sont sélectionnées avec le caractère *.
  2. Le parser pour le format du journal d'Apache interprète les champs.
  3. Seules les requêtes dont le statut de réponse HTTP est 200 sont conservées. En effet, de nombreuses requêtes sont invalides et ne nous intéressent pas. Par exemple, des requêtes émanant de robots à la recherche de vulnérabilités à exploiter.
  4. De façon étrange, le user agent est contenu dans le champ contentlength. Si le champ contient la chaîne de caractères "bot", on définit le champ bot_req à 1, sinon à 0. On peut étendre cette condition pour inclure les termes moins fréquents "crawler" et "spider".
  5. Enfin, la valeur moyenne du champ bot_req est calculée.

Quels sont les robots les plus actifs ?

Voici la liste des cinq robots les plus actifs sur ce site en 2024.

Rang Nom du robot Propriétaire Part des requêtes HTTP
1 Googlebot Google 4.72 %
2 GPTBot OpenAI 2.82 %
3 bingbot Microsoft 1.50 %
4 YandexBot Yandex 1.34 %
5 Bytespider ByteDance 1.01 %

Comment a évolué l'activité des robots au cours de l'année ?

Les graphiques qui suivent représentent l'activité des robots les plus connus sous la forme d'une carte thermique du calendrier.

Chaque case symbolise un jour de l'année. Les jours se suivent verticalement du lundi au dimanche et sont groupés par mois. La couleur d'une case varie du jaune pâle au rouge foncé en fonction du nombre de requêtes HTTP reçues ce jour là.

Les graphiques sont affichés par la bibliothèque JavaScript Cal-Heatmap.

Googlebot

Très actifs, les robots de Google ont visité le site tous les jours en 2024.

GPTBot

Les robots d'OpenAI ont visité le site 212 jours en 2024. Rares en début d'année, ils ont été très présents en octobre.

Bingbot

Les robots de Microsoft ont visité le site tous les jours en 2024.

YandexBot

Les robots de Yandex ont visité le site 342 jours en 2024 mais ont été plus discrets à partir du mois de septembre.

Bytespider

Les robots de ByteDance ont visité le site 254 jours en 2024 et ont été plus actifs de juillet à septembre.

AmazonBot

Les robots d'Amazon apparaissent au septième rang et se distinguent dans leurs accès : ils indexent l'ensemble du site une fois par mois.

ClaudeBot

Classés au neuvième rang par leur activité, les robots d'Anthropic ont visité le site 50 jours en 2024, principalement en avril et en mai.

IA quelqu'un ?

Les robots représentent une part croissante des visiteurs de ce site. Ils deviendront peut-être majoritaires en 2025.

Toutefois, j'aimerais qu'ils butinent plus sobrement le contenu du site pour ne pas consommer inutilement ses ressources informatiques.

Ils pourraient s'inspirer de l'efficacité discrète de ce butineur insaisissable.

Un Moro-sphinx (Macroglossum stellatarum) butine du Chèvrefeuille.

Un Moro-sphinx (Macroglossum stellatarum) butine du Chèvrefeuille.

XZ backdoor lessons: reproducing target-isns release tarballs

Andres Freund detected a backdoor in XZ, a data compression library, and disclosed it as CVE-2024-3094 at the end of March 2024.

Many good articles describe how the attackers implanted the backdoor:

The attackers prepared the backdoor for more than two years and completed their work when they became maintainers. They published a release tarball with a malicious build script not present in the source code. The attackers uploaded the release tarball to GitHub.

I maintain target-isns, a niche free software project packaged in several Linux distributions. There is not much activity in the project because it is mostly done. The last release of target-isns – version v0.6.8 – happened in May 2020. I built the release tarball on my machine and uploaded it to GitHub.

I believe that one of the lessons of the XZ backdoor episode is "Trust, but verify". Applied to target-isns releases I published, this could mean:

  1. How can users verify that the release tarball of target-isns matches the source code?
  2. How can we improve the release process of target-isns to ease that verification?

How to verify a release tarball built with git-archive

target-isns is written in C and built with CMake. A custom target, named dist, invokes git-archive to generate a tarball of the source code. Ironically, the tarball is compressed with XZ.

To verify that the release tarball matches the source code, we must compare the checksum of the published release tarball with one built locally from the source code.

How to compute the checksum of the published release tarball

Let's download the release tarball for target-isns v0.6.8 from GitHub and compute its SHA256 checksum:

$ curl -OL --silent https://github.com/open-iscsi/target-isns/releases/download/v0.6.8/target-isns-0.6.8.tar.xz
$ sha256sum target-isns-0.6.8.tar.xz
544de09a2073242b21f6859841a5016c79c4006a53435a79b5cfc6602a59db97  target-isns-0.6.8.tar.xz

How to reproduce the release tarball from the source code

We clone the repository with git clone and checkout the tag we want with --branch v0.6.8:

$ git clone --branch v0.6.8 https://github.com/open-iscsi/target-isns.git
$ cd target-isns

The command git show v0.6.8 reports that the tagger (it's me) signed the tag with GnuPG.

My about page mentions the fingerprint of my public GnuPG key. We import that key 1.

$ gpg --keyserver keyserver.ubuntu.com --search-key 81D01C4E399FFEDEDBD93D7F08390B7DF2FC1876
gpg: data source: http://185.125.188.27:11371
(1)     Christophe Vu-Brugier <cvubrugier@example.org>
          4096 bit RSA key 08390B7DF2FC1876, created: 2011-06-16
Keys 1-1 of 1 for "81D01C4E399FFEDEDBD93D7F08390B7DF2FC1876".  Enter number(s), N)ext, or Q)uit > 1
gpg: key 08390B7DF2FC1876: public key "Christophe Vu-Brugier <cvubrugier@example.org>" imported
gpg: Total number processed: 1
gpg:               imported: 1

After importing my public key, we verify the tag with git tag --verify 1:

$ git tag --verify v0.6.8
object 52e4fd427b1aff902ef4e7bce9a9c2f6b358a5eb
type commit
tag v0.6.8
tagger Christophe Vu-Brugier <cvubrugier@example.org> 1588947171 +0200

target-isns v0.6.8
gpg: Signature made Fri May  8 14:13:16 2020 UTC
gpg:                using RSA key 81D01C4E399FFEDEDBD93D7F08390B7DF2FC1876
gpg:                issuer "cvubrugier@example.org"
gpg: Good signature from "Christophe Vu-Brugier <cvubrugier@example.org>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 81D0 1C4E 399F FEDE DBD9  3D7F 0839 0B7D F2FC 1876

The tag signature is correct. We build a release tarball and compare its checksum with the published release tarball.

# mkdir build
$ cd build/
$ cmake ..
-- The C compiler identification is GNU 12.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /target-isns/build
$ make dist
Built target dist
$ sha256sum target-isns-0.6.8.tar.xz
544de09a2073242b21f6859841a5016c79c4006a53435a79b5cfc6602a59db97  target-isns-0.6.8.tar.xz

The checksum (544de09a) of the generated tarball matches the checksum of the published tarball: we reproduce the release tarball.

I reproduced the release tarball on Debian 12 (bookworm). Does that work with other Linux distributions?

Reproducing the release tarball from other Linux distributions

I use Podman to build the release tarball in several Linux containers.

Linux distribution Release tarball reproduced Git version XZ version
Alpine 3.19.1 Yes 2.43.0 5.4.5
Arch Linux No 2.44.0 5.6.1
Debian 11 (bullseye) Yes 2.30.2 5.2.5
Debian 12 (bookworm) Yes 2.39.2 5.4.1
Fedora 39 Yes 2.44.0 5.4.4
Ubuntu 22.04 (jammy) Yes 2.34.1 5.2.5
Ubuntu 24.04 (noble, pre-release) Yes 2.43.0 5.4.5
Rocky Linux 8 Yes 2.39.3 5.2.4
Rocky Linux 9 Yes 2.39.3 5.2.5

The release tarball is reproducible everywhere except on Arch Linux. The output of git archive is the same but XZ compresses the tarball differently. A binary search with git bisect finds the commit that introduce the change:

XZ (version 5.6.1) on Arch Linux compresses data with several threads by default. With --threads=1, we can force XZ to compress data with just one thread. With that, we can reproduce the release tarball of target-isns on Arch Linux.

Usually, there are different ways for a compressor to represent the original data. That's why a compressor output may differ when its algorithm or parameters change. To reduce the risk of compressed tarballs varying across platforms, target-isns releases could switch to a compressor less likely to change such as gzip.

Future work

While existing release tarballs of target-isns are reproducible, we should improve the release process.

Document the release process.
A document should describe how releases are made and how to reproduce them.
Setup a continuous integration pipeline to generate the release tarball from a tag.
A continuous integration job should automatically generate the release tarball from a tag. The job should run in a container (for example a Docker image). With that, users could reproduce the release tarballs by running the same container image on their machine.
Sign the release tarball with GnuPG.
The maintainer should download the tarball generated by the release pipeline, reproduce it, and test it. Then, they should publish the release tarball, the SHA256 checksum file, and sign these files with their private GnuPG key.
A crab spider (Misumena vatia) caught a bee.

A crab spider (Misumena vatia) caught a bee.


  1. I removed my email from the command output. 

Statistiques d'accès au site en IPv6

Le mois dernier, j'ai observé que bien que mon serveur Web possédât une adresse IPv6, aucun navigateur Web ne s'y connectait via ce protocole. J'avais tout simplement oublié d'associer un enregistrement IPv6 address record au nom de mon domaine dans la zone DNS.

Un mois plus tard, la lecture des logs de mon serveur Web confirme qu'une partie des navigateurs Web s'y connectent en IPv6 et je peux mesurer dans quelle proportion.

Dites AAAA

Sur Internet, le service DNS associe les noms de domaine Internet avec leurs adresses IP.

La plupart des sites Internet déclarent des adresses IPv4 dans leur zone DNS à travers des enregistrements DNS A (A pour Adresse).

Conscients de l'épuisement des adresses IPv4, de plus en plus de sites Internet sont aussi accessibles en IPv6. Pour permettre aux navigateurs Web de résoudre leur nom de domaine en adresses IPv6, ils ajoutent des enregistrements DNS AAAA dans leur zone DNS. Les quatre "A" dénotent le fait qu'une adresse IPv6 (128 bits) est quatre fois plus longue qu'une adresse IPv4 (32 bits).

Sous Linux, l'outil dig permet d'effectuer des requêtes DNS en ligne de commande et donc de vérifier si un site Internet déclare être accessible en IPv4 et en IPv6.

Pour afficher l'adresse IPv4 associée à un nom de domaine :

$ dig +short enodev.fr A
159.69.222.76

Et pour obtenir l'adresse IPv6 éventuellement associée :

$ dig +short enodev.fr AAAA
2a01:4f8:1c1e:b2d0::1

Qui AAAAccède ?

Le fichier journal des accès du serveur HTTP Apache enregistre les requêtes qu'il a traitées.

Dans le format par défaut du fichier journal des accès, l'adresse IP du client figure au début de chaque ligne.

L'extrait de journal suivant présente une requête HTTP effectuée par un navigateur Web connecté en IPv4 suivie d'une requête formulée par un autre navigateur Web connecté en IPv6 :

24.35.90.123 - - [01/Oct/2023:00:03:20 +0200] "GET /posts/rusticity-convert-an-integer-to-an-enum.html HTTP/2.0" 200 6966 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36"
2a02:8308:285:e800:9807:3eea:1a93:1234 - - [01/Oct/2023:00:03:30 +0200] "GET /posts/rusticity-convert-an-integer-to-an-enum.html HTTP/2.0" 200 6966 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.43"

Analyse des accès avec Angle-grinder

Angle-grinder est un outil en ligne de commande qui permet d'interpréter des données en effectuant des opérations de tri, de sélection, de groupement, ou des calculs. Angle-grinder est notamment capable d'interpréter directement un fichier journal des accès d'Apache. Ceci va nous aider à mesurer dans quelle proportion les navigateurs Web se connectent au site en IPv6.

Voici une façon de compter le nombre d'adresse IP différentes qui se sont connectées au serveur HTTP avec Angle-grinder:

$ agrind -f apache.log "* | apache | count_distinct(ip) as unique_ipaddrs"
unique_ipaddrs
----------------------
5326

Les pipelines, séparés par le caractère |, sont composés ainsi :

  1. Toutes les entrées du fichier journal sont sélectionnées avec le caractère *.
  2. Le parser pour le format du journal d'Apache interprète les champs.
  3. L'opérateur d'agrégation count_distinct() est appelé sur le champ nommé ip. La colonne de résultat est nommée unique_ipaddrs.

Pour dénombrer le nombre d'adresse IPv6 différentes, il suffit d'ajouter un filtre qui sélectionne les adresses IP qui contiennent le séparateur :.

$ agrind -f apache.log "* | apache | contains(ip, ':') as is_ipv6 | where is_ipv6 | count_distinct(ip) as unique_ipv6addrs"
unique_ipv6addrs
------------------------
500

9,4 % des navigateurs Web se connectent donc au site en IPv6. La part des requêtes HTTP effectuées en IPv6 est assez proche – 10 % – comme on peut le constater avec la requête suivante :

$ agrind -f apache.log "* | apache | contains(ip, ':') as is_ipv6 | if(is_ipv6, 1, 0) as ipv6_req | avg(ipv6_req) as ipv6_req_ratio"
ipv6_req_ratio
----------------------
0.10

Il sera intéressant de suivre la progression du ratio des accès réalisés en IPv6 dans le temps.

Note: en décembre 2024, 14 % des requêtes HTTP sont effectuées en IPv6.

Une épeire fasciée sur sa toile. Connectée en IPv6 ?

Une épeire fasciée sur sa toile. Connectée en IPv6 ?

Réalisation d'un nichoir bûche

Au printemps 2018, j'ai construit un nichoir pour mésange charbonnière à partir d'une grosse bûche. Cet abri a depuis accueilli plusieurs nichées, signe que les mésanges s'y plaisent. Puisque la période de nidification approche, voyons comment réaliser ce type de nichoir simple et rustique.

Matériel

  • Une bûche. Dans mon cas, les dimensions étaient les suivantes : longueur = 34 cm, diamètre = 18 cm.
  • Une hache à fendre.
  • Une scie à bûche.
  • Une scie à cloche.
  • Un marteau.
  • Des clous.
  • Des vis à bois.
  • Des pattes d'assemblage.

Étapes de construction

  1. Scier deux rondelles aux extrémités. Elle constitueront la base et le toit.

  2. Fendre la bûche en quatre dans le sens de la longueur.

  3. Fendre chaque quartier en biais pour constituer la pièce à vivre.

    Pour une mésange charbonnière, la surface au sol minimale est un carré de 10 cm de côté (0.01 m2 loi Carrez). La hauteur sous plafond conseillée est d'environ 25 cm.

  4. Dégrossir les bords intérieurs sans chercher à les rendre lisses : les aspérités permettent aux oiseaux de grimper.

  5. Percer le trou d'envol. Le diamètre conseillé pour une mésange charbonnière est de 32 à 34 mm.

  6. Clouer les murs à la base.

  7. Visser les pattes de fixation pour finir d'assembler les murs.

  8. Caler le toit. Le toit doit être amovible pour permettre de nettoyer l'intérieur du nichoir mais il ne doit pas s'envoler au moindre coup de vent.

Découpe de la loge
Assemblage des parois
Nichoir bûche achevé

Place à l'observation

La construction de votre nichoir bûche est achevée. Une fois solidement fixé à un arbre, nul doute qu'un couple de mésanges ne tardera pas à le remarquer et à y faire son nid douillet. À bonne distance – pour ne pas les déranger – vous aurez tout loisir d'observer leur va-et-vient incessant. Bonne observation !

Mésange charbonnière au nichoir

Mésange charbonnière au nichoir

Fin du QIF à la Société Générale

J'utilise GnuCash depuis une dizaine d'années pour tenir mes comptes. J'ai l'habitude d'importer le relevé des opérations au format QIF dans GnuCash. Or depuis la refonte du site Internet destiné aux particuliers, la Société Générale ne propose plus l'export du relevé des opération au format QIF. À la place, la banque au carré rouge et noir propose un fichier CSV contenant les opérations réalisées au cours des six derniers mois.

Contactée, la Société Générale m'a informé « ne pas pouvoir changer le format proposé par le site ».

Je constate qu'à l'image des GAFAM, la Société Générale cherche à capter les données de ses clients pour les exploiter et néglige leur partage avec ces mêmes clients qui en sont pourtant les propriétaires. Ainsi, le site Internet de la Société Générale propose d'importer des comptes externes, c'est-à-dire tenus dans d'autres établissements bancaires. Mais quiconque veut rapatrier ses données doit se contenter d'un fichier CSV réduit à la portion congrue.

Nous allons étudier les problèmes liés au fichier CSV fourni par la Société Générale et développer ensemble l'esprit d'équipe une solution pour faciliter son import dans GnuCash.

Du CSV à la française

Après avoir téléchargé le fichier CSV, observons ses propriétés :

$ file Export_17052019_16112019.csv
Export_17052019_16112019.csv: ISO-8859 text, with CRLF line terminators

Le fichier est encodé en ISO 8859 et les retours à la ligne sont matérialisés par deux octets CR+LF comme il est d'usage sous Windows.

Que contiennent donc nos données ?

$ head Export_17052019_16112019.csv
="0201900016400270";17/05/2019;16/11/2019;
date_comptabilisation;libellé_complet_operation;montant_operation;devise;
15/11/2019;CARTE X7527 15/11 METRO    ;-14,90;EUR;
13/11/2019;VIR RECU    8527975563S DE: Boulot SAS MOTIF: BOULOT OCTOBRE 2019 33 REF: BOULOT OCTOBRE 2019 33;2188,28;EUR;
11/11/2019;PRELEVEMENT EUROPEEN 7997325297 DE: DODO GESTION ID: FR65ZZZ233162 MOTIF: 081 LOYER DODO;-614,50;EUR;
10/11/2019;CARTE X7527 10/11 RESTO    ;-11,00;EUR;
09/11/2019;CARTE X7527 09/11 BRICO    ;-14,50;EUR;

Nous avons affaire à la variante française du CSV qui utilise le point-virgule pour délimiter les colonnes et la virgule pour partager la partie entière et la partie décimale d'un nombre.

La première ligne débute par le numéro de compte. La notation ="0123" est une astuce pour indiquer à Microsoft Excel de préserver le zéro au début d'un nombre. Suivent les dates de début et de fin des données exportées. Les dates sont exprimées au format français JJ/MM/AAAA.

La deuxième ligne contient les intitulés de colonnes qui sont donc la date de comptabilisation, le libellé de l'opération, son montant et la devise. Nous remarquons que la ligne se termine par un séparateur point-virgule inutile.

Nettoyer le fichier CSV avec Pandas

Après avoir observé les données, nous ouvrons notre boîte à outils d'apprenti Data Scientist. Nous choisissons Python et Pandas. Python est un langage de programmation qu'on ne présente plus : il est même enseigné au Lycée. Pandas est une bibliothèque Python destinée à la fouille de données. Python et Pandas, voilà une excellente compagnie pour le paresseux que je suis.

Charger

La bibliothèque Pandas fournit la fonction read_csv() avec de nombreux paramètres permettant de nettoyer le fichier CSV.

import pandas as pd

df = pd.read_csv('Export_17052019_16112019.csv',
                 sep=';', decimal=',', header=1,
                 parse_dates=True, dayfirst=True,
                 usecols=range(4), index_col=0,
                 names=['date', 'description', 'amount', 'currency'],
                 encoding='ISO-8859-1')

Parmi les paramètres :

  • sep et decimal adaptent le comportement de read_csv() pour la variante française du CSV.
  • header indique que la ligne des entêtes est la deuxième ligne (la première ligne ayant pour indice zéro).
  • dayfirst sélectionne le format de date européen où le jour apparaît avant le mois (les États-Unis fêtent Noël le 12/25).
  • index_col précise que la première colonne – la date – sert d'index.

La fonction read_csv() retourne un objet de type DataFrame. Voici son contenu affiché par Python :

>>> df
                                                  description   amount currency
date
2019-11-15                        CARTE X7527 15/11 METRO       -14.90      EUR
2019-11-13  VIR RECU    8527975563S DE: Boulot SAS MOTIF: ...  2188.28      EUR
2019-11-11  PRELEVEMENT EUROPEEN 7997325297 DE: DODO GESTI...  -614.50      EUR
2019-11-10                        CARTE X7527 10/11 RESTO       -11.00      EUR
2019-11-09                        CARTE X7527 09/11 BRICO       -14.50      EUR

Filtrer

La version précédente du site Internet de la Société Générale proposait d'exporter les transactions au format QIF depuis le dernier téléchargement. La nouvelle mouture propose un export au format CSV des transactions des six derniers mois.

Par conséquent, nous sommes désormais contraint de relever dans GnuCash la date de la dernière transaction déjà importée afin de filtrer les données CSV à importer et limiter les doublons.

La première colonne – la date – ayant été choisie comme index, l'opération se fait simplement avec un slice :

>>> df = df['2019-11-15':'2019-11-13']
>>> df
                                                  description   amount currency
date
2019-11-15                        CARTE X7527 15/11 METRO       -14.90      EUR
2019-11-13  VIR RECU    8527975563S DE: Boulot SAS MOTIF: ...  2188.28      EUR

Distinguer les dépôts et les retraits

Le CSV exporté depuis le site Internet de la Société Générale comprend une seule colonne montant. Or GnuCash exige de distinguer dépôt et retrait.

Nous devons donc ajouter deux colonnes au tableau et les remplir à partir du montant.

Pour une transaction donnée :

  • Si le montant est positif, il s'agit d'un dépôt. Nous copions la valeur du montant dans la colonne dépôt et nous écrivons zéro dans la colonne débit.
  • Si le montant est négatif, il s'agit d'un retrait. Nous copions la valeur absolue du montant dans la colonne retrait et nous écrivons zéro dans la colonne dépôt.

Avec Pandas, les colonnes dépôt et retrait peuvent être calculées à partir du montant de la manière suivante :

df['deposit']  = df['amount'].apply(lambda x: x if x > 0 else 0)
df['withdraw'] = df['amount'].apply(lambda x: abs(x) if x < 0 else 0)

En Python, le mot clé lambda définit une fonction anonyme. Dans la première instruction, la colonne dépôt est remplie en appliquant au montant la fonction qui pour x retourne x s'il est positif et 0 dans le cas contraire.

Voici à quoi ressemble notre tableau suite à l'ajout des colonnes dépôt et retrait :

                                                  description   amount currency  deposit  withdraw
date
2019-11-15                        CARTE X7527 15/11 METRO       -14.90      EUR     0.00      14.9
2019-11-13  VIR RECU    8527975563S DE: Boulot SAS MOTIF: ...  2188.28      EUR  2188.28       0.0

Exporter à destination de Gnucash

La méthode to_csv() permet de sauvegarder un DataFrame dans un fichier au format CSV.

df.to_csv('gnucash.csv',
          sep=';', decimal=',',
          columns=['description', 'deposit', 'withdraw'])

Seules sont exportées les colonnes utiles à GnuCash : date (implicite car il s'agit de l'index), description, dépôt, et retrait.

Notre fichier CSV « nettoyé » est prêt à être importé dans GnuCash.

Importer le fichier CSV final dans GnuCash

Dans l'interface graphique de GnuCash, nous cliquons sur : fichierimporterimporter des transactions depuis un CSV.

Après avoir sélectionné notre fichier CSV, GnuCash nous présente la fenêtre d'aperçu de l'import.

Aperçu de l'import dans GnuCash

Nous appliquons les réglages suivants :

  • Le point-virgule est défini comme séparateur de colonnes.
  • La première ligne qui correspond à l'entête est ignorée.
  • Le type des données de chaque colonne est précisé.
  • Un compte cible est renseigné pour l'ensemble des transactions (champ account).

Le wiki de GnuCash décrit plus en détail comment importer des transactions au format CSV.

Pour aller plus loin

Le script csv-socgen.py reprend l'ensemble du code présenté ici. Il ne s'agit que d'un premier jet.

Le script mérite d'être amélioré pour remplir automatiquement le compte destinataire et modifier la description si elle correspond à un motif donné. Ainsi, le compte destinataire de la transaction ayant pour description METRO serait automatiquement renseigné en Dépenses:Transports publics:Métro. Remarquons que la banque affiche une catégorie pour chaque transaction sur son site Internet mais que cette information ne figure pas dans le fichier CSV. À nous de ruser.

Un ancien slogan de la Société Générale clamait « On est là pour vous aider ». Cette ambition a disparu en 2019 avec un slogan devenu « C'est vous l'avenir ». Alors, ne comptez que sur vous-même pour tenir vos comptes !