Blog

Fév 07

Analyse de structure interne d’un site

J’embarque assez souvent dans mes prestations une analyse de la structure interne des sites clients. On va parler aujourd’hui de ma méthodologie et je vais vous présenter quelques-uns des outils (développés maison) que j’utilise.

Je tiens à remercier mon confrère Aurélien Berrut, dont les travaux (ici et ici) m’ont très largement inspiré pour la partie « visualisation » (avec Gephi).

Je vais logiquement en garder sous le pied pour plusieurs raisons : 1) chaque cas est différent et je vais devoir me cantonner aux généralités; 2) pour une application exhaustive et des recommandations pratiques pour votre site, il va falloir passer par la case devis.

LE CRAWL

Avant d’analyser, il faut collecter. Pour cela, on va se servir d’un crawler dont le principe est le suivant : on télécharge la homepage, qui sera la seule page de profondeur 0 et la base du crawl. On note les liens qu’on y trouve, ce seront les pages de profondeur 1. Pour chaque URL, on répète l’opération, jusqu’à avoir épuisé la liste de toutes les URLs présentes sur le site. Pour réaliser le crawler, on choisira un langage comme le Perl, le Python ou le Ruby, qui possèdent de bonnes capacités de multithreading, bien qu’il soit possible de garder des langages plus courants comme le PHP (même si ça n’a pas grand intérêt).

Étant très à l’aise avec ce moteur de stockage, j’enregistre les résultats dans une base MySQL en utilisant deux tables : les URLs d’un côté, et les Liens de l’autre.

Pour la petite histoire, j’ai bossé sur un crawler de ce genre en C++ (en utilisant le framework Qt). J’ai laissé tomber cette techno car le parsing XML/HTML en C++ est assez hasardeux et en nettoyant le code avec Tiny, je m’éloignais d’une copie pure du site et m’infligeais des séances de code nocturnes assez monstrueuses. Par contre, les performances étaient AU TOP.

LA COPIE EN BASE ET LES PREMIERS CONSTATS

Le résultat est une copie complète, un peu comme un moulage, du site. C’est là que les réjouissances commencent. En quelques requêtes SQL, on peut avoir :

  • le nombre de pages par niveau de profondeur
  • les pages recevant le plus / le moins de liens
  • la répartition des différentes ancres des liens qui pointent vers une même page
  • etc, etc…

Le nombre de pages par niveau de profondeur (nombre de clics depuis la page d’accueil pour accéder à un contenu) donne une bonne première approche de la structure. Je l’imagine comme une pyramide, la homepage étant tout en haut. Si le nombre de pages des niveaux inférieurs montre rapidement, on peut imaginer une navigation avec de nombreux liens. A l’inverse, si le nombre monte lentement, on peut imaginer une nav assez pauvre.

La liste des pages recevant le plus de liens m’intéresse aussi : on y retrouve souvent des pages qui n’ont aucun intérêt en SEO : contact, mentions légales… qui gaspillent un précieux link juice. A l’inverse, on trouve souvent dans les pages « enfouies » (grande profondeur, corollaire du peu de liens qu’elles reçoivent) des pages produits, qui gagneraient à être mieux placées dans l’arbo.

Même remarque pour la répartition des ancres internes (corpus des textes cliquables de l’ensemble des liens qui mènent à une page) : alors chaque consultant SEO qui se respecte garde un oeil permanent sur la répartition des ancres des liens externes d’un site, un nombre relativement important de structures internes ne linkent chaque page qu’avec un seul mot-clef. On est loin d’une distribution sémantique optimale

REPRÉSENTATION VISUELLE : ENCORE QUELQUES CONSTATS

C’est à ce niveau qu’on lance Gephi. Après avoir préparé deux fichiers CSV, l’un pour les nodes (urls) et l’autre pour les edges (liens), on obtient un graphe comme celui présenté en intro de cet article. Ici, c’est un blog WordPress. L’analyse a été réalisée très tôt dans la vie du blog, avant son lancement : il est en cours de remplissage et ne présente que quelques articles.

J’importe les nodes et edges dans Gephi. J’applique une couleur par profondeur et une taille qui dépend du nombre de liens reçus. Je spatialise suivant l’algorithme Force Atlas. On identifie alors immédiatement la homepage, seule page de niveau 0 (en rouge au centre), puis les pages de catégories principales (en orange, autour).

Premier constat : la grappe de pages en bas à gauche du graphe représente les pages de tags. Bien que faiblement linkées, elles représentent un pourcentage non négligeable des pages de profondeur 2. Autre constat : les pages de profondeur 3 (cercles blanc) sont des pages de galleries, générées par NextGEN Gallery, et qui, ne présentant pas d’intérêt particulier (puisque chaque gallerie est embarquée dans un post), ne devraient pas être indexables.

Avec un peu d’entraînement, chaque type de site a une topologie facile à reconnaître. Par exemple, un blog WordPress intégré au forceps dans une boutique e-commerce laisse un footprint très caractéristique, qui permet d’orienter rapidement les chantiers d’optimisation.

AJOUTER LES LOGS APACHE/GOOGLEBOT

Connecté en SSH, je récupère dans les fichiers access.log (logs Apache), les lignes qui correspondent au robot d’indexation de Google. Dans le cas où j’ai un logrotate qui fait une rotation/compression des logs, je me sers de la commande suivante :

zgrep « Googlebot » access.log* > google.log

(plus élégant que décompresser d’énormes fichiers sur le disque, pour les lire ensuite)J’ai ensuite un script qui lit, ligne par ligne, les logs en question. Pour chaque ligne, il récupère l’URL de la requête, la compare avec la listes des URLs indexées par mon crawler, incrémente le nombre de hits reçus, stocke la date du dernier crawl, etc.

Il ne me reste qu’à taper une requête pour recevoir la liste des pages classées par nombre de hits descendants. De la même manière, je peux récupérer la liste des pages n’ayant pas été crawlées sur une période donnée (la dernière semaine, la dernière journée…)

Je peux même refaire un graphe Gephi en indexant la couleur des cercles sur la date du dernier crawl…

About The Author

Leave a reply

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *