Aller au contenu

De la variété dans les fournisseurs d'adresse email

J'ai voulu savoir quelle proportion de mes contacts utilise une adresse email GAFAM. Pour cela, j'ai créé un petit script python qui parse mon carnet d'adresses et compte les noms de domaines.

Le problème de la centralisation de l'Internet

En 2007, Benjamin Bayart donnait la conférence "Internet Libre ou Minitel 2.0 ?" à Amiens. Au cours de cette conférence, Benjamin expliquait, entre autres, que l'Internet est de plus en plus centralisé. En effet, lorsqu'il a été créé, l'Internet reposait sur le principe que chaque ordinateur qui lui est connecté permet de partager du contenu, et d'accéder au contenu des autres. Mais Benjamin constate qu'aujourd'hui, quelques gros ordinateurs (les fournisseurs de services) concentrent les données, et les autres ne font que les consulter.

Cette centralisation de l'Internet entraîne plusieurs problèmes :

  • Les utilisateurs perdent le contrôle de leurs données, puisqu'elle ne sont plus partagées depuis leur ordinateur, mais depuis celui des fournisseurs de services.

  • L'utilisateur se voit obligé d'accorder sa confiance à ces fournisseurs, puisqu'il ne maîtrise pas leur architecture ou les logiciels qu'ils utilisent. Or, force est de constater que ces fournisseurs de services abusent de cette confiance et utilisent les données que les utilisateurs leur confient de façons plus que douteuses. Je vous invite à consulter le blog de Tristan Nitot, qui répertorie réguliairement les dérives et scandales liés aux géants du Net.

  • La mise en place d'une surveillance généralisée, qui vient restreindre la liberté d'expression, et met en danger nos démocraties.

  • Une concentration de pouvoirs et de responsabilités, qui pose de vrais problèmes de sécurité des données, et de leur exploitation.

C'est pour lutter contre cette centralisation que j'administre un petit serveur chez moi, qui héberge mes données, mes emails, mes services. C'est ce que l'on appel l'auto-hébergement.

Impact sur les courriels

Il me semble que cette centralisation est vraie notamment dans le cas du courrier électronique. Parmi mes contacts, combien sont chez gmail, hotmail ou yahoo ? C'est pour répondre à cette question que j'ai tenté cette petite expérience : j'ai exporté mon carnet d'adresse au format vcf, et j'ai fait un petit script python qui liste les adresses de courriel et les tri par nom de domaine (le @machin.truc). Je vous laisse interpréter le résultat :

  • gmail.com : 42.11 %
  • yahoo.fr : 11.65 %
  • hotmail.fr : 11.28 %
  • hotmail.com : 7.52 %
  • free.fr : 4.14 %
  • orange.fr : 3.01 %
  • wanadoo.fr : 1.88 %
  • laposte.net : 1.50 %
  • sfr.fr : 0.75 %
  • yahoo.com : 0.75 %
  • live.fr : 0.75 %
  • neuf.fr : 0.75 %
  • outlook.com : 0.75 %
  • yahoo.it : 0.38 %
  • icloud.com : 0.38 %
  • aol.com : 0.38 %
  • voila.fr : 0.38 %
  • msn.com : 0.38 %
  • autre : 11.28 %

La catégorie autre correspond aux courriels d'entreprises, ainsi que mes rares amis qui s'auto-hébergent.

Un peu de Python

Voici le script utilisé pour générer cette liste :

import sys
import re
import operator

def main(file_path):
    domains = dict()
    with open(file_path, 'r') as input_file:
        content = input_file.read()
        match = re.findall(r'[\w\.-]+@[\w\.-]+', content)
        print("This file contains {} email addresses.".format(len(match)))
        for email in match:
            domain = email.split('@')[1]
            domains[domain] = domains.get(domain, 0) + 1
    sorted_domains = sorted(domains.items(), key=operator.itemgetter(1), reverse=True)
    for domain, number in sorted_domains:
        print("  - {dom} : {num:.2f} %".format(dom=domain, num=float(number) / float(len(match)) * 100.))

if __name__ == "__main__":
    main(sys.argv[1])

Le dictionnaire domains contient en clé le nom de domaine et en valeur le nombre de contacts utilisant le domaine. J'utilise une expression régulière pour trouver toutes les adresses dans le fichier : [\w\.-]+@[\w\.-]+, ainsi la variable match contient une liste de courriels. Il s'agit donc de parcourir cette liste et de regarder le domaine de chaque adresse.

La ligne suivante permet d'incrémenter le dictionnaire domains, et créé la clé si elle n'existe pas (première fois que le domaine est rencontré) :

domains[domain] = domains.get(domain, 0) + 1

Le fait d'utiliser domains.get() permet d'avoir une valeur par défaut au cas où le domaine n'existe pas encore dans les clés.

Pour rendre le résultat plus lisibles, j'avais envie de le trier par ordre du domaine le plus fréquent au domaine le plus rare. En Python, les dictionnaires n'étant pas triés, j'utilise sorted() sur les clés et valeurs du dictionnaire pour obtenir une liste de tuples :

sorted_domains = sorted(domains.items(), key=operator.itemgetter(1), reverse=True)

Se limiter aux domaines principaux

Parmi mes contacts, il y a quelques professionnels qui utilisent un domaine dédié à leur entreprise. Souhaitant me concentrer sur les fournisseurs de courriel grand public, j'ai regroupé tous les domaines "exotique" en une catégorie autres. Pour ce faire, j'ai initialisé mon dictionnaire domains avec les domaines qui m'intéressent.

domains = {'gmail.com': 0, 'hotmail.fr': 0, 'yahoo.fr': 0,
           'free.fr': 0, 'sfr.fr': 0, 'hotmail.com': 0,
           'yahoo.com': 0, 'live.fr': 0, 'orange.fr': 0,
           'yahoo.it': 0, 'icloud.com': 0, 'laposte.net': 0,
           'neuf.fr': 0, 'wanadoo.fr': 0, 'aol.com': 0,
           'voila.fr': 0, 'msn.com': 0, 'outlook.com': 0,
           'other': 0}

Il faut aussi ajouter une condition pour attribuer tous les domaines "exotiques" à la catégorie autre

domain = email.split('@')[1]
if domain not in domains:
    domain = 'other'
domains[domain] = domains.get(domain, 0) + 1

Afficher un camembert

Pour avoir une représentation graphique de la répartition des domaines utilisés par mes contacts, le camembert me semble judicieux. Avec la bibliothèque matplotlib, rien de plus simple :

fig1, ax1 = plt.subplots()
ax1.pie(domains.values(), labels=domains.keys(), startangle=90)
ax1.axis('equal')
plt.savefig('pie.png')
plt.show()

Ce qui nous donne :

Camembert de répartition des domaines

Regrouper par entreprise

Plusieurs noms de domaines peuvent correspondre à une même entrepris. Par exemple, hotmail.fr, live.fr et msn.com correspondent tous les 3 à Microsoft. J'ai donc décidé de regrouper les domaines par entreprise. Voici le script modifié :

import sys
import re
import pandas as pd
import matplotlib.pyplot as plt

def main(file_path):
    domains = {'gmail.com': "Google", 'hotmail.fr': "Microsoft", 'yahoo.fr': "Yahoo",
               'free.fr': "Free", 'sfr.fr': "SFR", 'hotmail.com': "Microsoft",
               'yahoo.com': "Yahoo", 'live.fr': "Microsoft", 'orange.fr': "Orange",
               'yahoo.it': "Yahoo", 'icloud.com': "Apple", 'laposte.net': "LaPoste",
               'neuf.fr': "SFR", 'wanadoo.fr': "Orange", 'aol.com': "AOL",
               'voila.fr': "Orange", 'msn.com': "Microsoft", 'outlook.com': "Microsoft"}
    count = pd.DataFrame({'colors': ['#304699', '#7a7e81', '#cc0000',
                                     '#34a853', '#ffc928', '#04a5f0', '#ff7900',
                                     '#e2001a', '#4b00c3', '#000000'],
                          'count': 0},
                         index=["AOL", "Apple", "Free", "Google",
                                "LaPoste", "Microsoft", "Orange", "SFR",
                                "Yahoo", "Other"])

    with open(file_path, 'r') as input_file:
        content = input_file.read()
        match = re.findall(r'[\w\.-]+@[\w\.-]+', content)
        print("This file contains {} email addresses.".format(len(match)))
        for email in match:
            company = domains.get(email.split('@')[1], "Other")
            count.loc[company, 'count'] += 1
    count.sort_values('count', ascending=False, inplace=True)
    print(count)

    ax = count.plot.pie(y='count', figsize=(6, 6), colors=count.colors, legend=False)
    ax.set_ylabel("")
    plt.savefig('pie.png')
    plt.show()


if __name__ == "__main__":
    main(sys.argv[1])

Désormais, le dictionnaire domains permet de faire la correspondance entre les noms de domaines et les entreprises. J'ai décidé d'utiliser pandas à la place d'un dictionnaire pour compter. Cela me permet d'ajouter d'autres information, comme une couleur correspondant aux entreprises. Cela permet aussi de voir quelques fonctionnalités intéressantes de cette bibliothèque, comme le tri et l'intégration de matplotlib.

Voici le nouveau camembert :

Camembert de répartition des entreprises

Comme vous pouvez le constater, trois entreprises concentrent les trois quart de mes contacts.