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 :
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 :
Comme vous pouvez le constater, trois entreprises concentrent les trois quart de mes contacts.