Analyse SEO – un robot pour le réfé­ren­ce­ment

Voici un article plutôt tech­nique mais la fina­lité de ce projet l’est beau­coup moins.

Un robot, craw­ler ou encore spider est un programme qui navigue sur un site web. Ça sert à beau­coup de choses, les moteurs de recherches s’en servent pour indexer les pages web, les spam­meurs pour récu­pé­rer les adresses web qui trainent sur les pages.

Et moi, que pour­rais-je bien en faire ?

La première fois que je me suis attaqué à la ques­tion c’était pour auto­ma­ti­ser la parti­ci­pa­tion à un concours à l’aide de PERL et Mecha­nize.

Aujourd’­hui, c’est plus pour de l’ana­lyse de site web. Oui, il y a plein d’ou­tils en ligne pour cela, mais aucun vrai­ment complet et gratuit à la fois. Je vais utili­ser Python et …

… la librai­rie à utili­ser sera le premier point de cet article.

Logi­ciels néces­saires

Biblio­thèques de crawl

Les forces en présence :

  • Lxml
  • html5­lib
  • HTMLPar­ser
  • html­fill
  • Genshi
  • Beau­ti­fulSoup
  • Et sans doute encore d’autres.

Il s’agit là de librai­rie, Bieau­ti­fulSoup semble la plus popu­laire suivi de pres par Lxml, mais Lxml est de loin le plus perfor­mant de la liste. Toute­fois, afin de me simpli­fier la tâche j’ai choi­sir d’uti­li­ser un frame­work, Scrapy.

Autres modules ou biblio­thèques

Scrapy utilise Xpath pour extraire les infor­ma­tions des pages web, c’est bien pratique pour les balises et lorsqu’on sait ce que l’on cherche, titre de la page (bali­se­si­tuée dans l’en­tête du docu­ment), liens (balises <a>), mais ce sera insuf­fi­sant pour détec­ter les autres liens, par exemple présents dans du javas­cript. Pour cela, je devrais utili­ser des expres­sions régu­lières.

On réca­pi­tule :

  • Xpath (via Scrapy)
  • Expres­sions régu­lières (dispo­nible par défaut)

Instal­ler Scrapy

Pour réali­ser les tests présen­tés dans cet article j’uti­lise mon Rasp­ber­ryPi, ceci est impor­tant car d’une plate­forme à l’autre l’ins­tal­la­tion de Python et les modules présents par défaut peuvent diffé­rer. Pour instal­ler Scrapy, la docu­men­ta­tion préco­nise l’une des commandes suivantes :

  • pip install Scrapy
  • easy_install Scrapy

Pip et Easy_install sont deux modules permet­tant d’ins­tal­ler faci­le­ment et propre­ment d’autres modules Python, hélas aucun des deux ne fonc­tionne :

>>> pip install Scrapy
 File "", line 1
 pip install Scrapy
 ^
SyntaxError: invalid syntax

>>> easy_install Scrapy
 File "",
 line 1 easy_install Scrapy
 ^
SyntaxError: invalid syntax

Une fois scrapy installé, il vous faudra instal­ler 3 autres biblio­thèques (si elles ne le sont pas déjà sur votre système :

  • Twis­ted
  • w3lib
  • Lxml

Voilà, c’est fait, passons à la suite.

Initia­li­ser un projet

Avec Scrapy, ça se passe ainsi :

scrapy startproject nom_du_projet

Et pour le reste du démar­rage avec, voici un tuto­riel Scrapy en VO sur le site offi­ciel et une présen­ta­tion de démar­rage en français.

Il faudra ensuite procé­der à quelques petits réglages :

  1. rendre le user-agent aléa­toire ;
  2. rendre aléa­toire le délai entre deux requêtes ;
  3. suivre ou non les règles du fichier robots.txt.

Confi­gu­rer Scrapy

Rendre le user-agent aléa­toire

Pourquoi rendre le user-agent aléa­toire ? Bien sûr il faut savoir ce qu’est un user-agent, si ça ne vous dit rien vous pouvez sauter ce chapitre.

En fait, je ne suis pas sûr que ce soit toujours néces­saire. Tout dépends de du site que vous audi­tez.

S’il s’agit d’un petit site, vous pouvez ne pas vous soucier du user-agent.

Sur un gros site, deux possi­bi­li­tés, vous avez à faire à un client dont le prin­ci­pal inté­rêt est :

  • La sécu­rité
  • Le réfé­ren­ce­ment / marke­ting

Client orienté sécu­rité

Dans le premier cas, il y a fort à parier que le site est blindé et qu’un inven­taire rapide et exhaus­tif ne passe pas. Chez ce genre de client, discu­ter avec le service tech­nique peut prendre beau­coup de temps, plus que l’in­ven­taire en lui-même.

Dans ce cas, la ruse est le meilleur recours. En modi­fiant le user-agent, on simule des utili­sa­teurs diffé­rents.

Pour aller plus loin, on pour­rait égale­ment faire tour­ner les adresses IP mais ça devient compliqué, ajou­ter à cela qu’il faut soit payer les proxies, soit se contenté de la médiocre qualité des proxies gratuits glanés çà et là sur inter­net.

Voici quand même quelques solu­tions pour les plus coura­geux :

Client orienté réfé­ren­ce­ment / marke­ting

Pour le moment, je ne vous ai présenté que les avan­tages des méthodes ci-dessus, mais le revers de la médaille c’est que ceci faus­ser vos statis­tiques.

Sur un très très gros site ceci passer peut-être inaperçu, mais imagi­nons que vous ayez à cœur de ne pas polluer les statis­tiques de votre client, dans ce cas, il serait préfé­rable d’uti­li­ser un IP unique et/ou un user-agent spéci­fique faci­le­ment repé­rable pour les écar­ter des stats.

Par défaut Scrapy indique son nom dans le user-agent, mais il est aussi possible de le défi­nir manuel­le­ment.

User-agent dyna­mique dans la pratique

J’ai utilisé le code à l’adresse suivante : https://github.com/svet­lyak40wt/scrapy-usera­gents

Marche à suivre rapide :

1. Copier le code suivant

DOWNLOADER_MIDDLEWARES = {
 # we'll turn off standart user agent middleware
 'scrapy.contrib.downloadermiddleware.useragent.UserAgentMiddleware': None,
 'scrapy_useragents.middleware.UserAgentsMiddleware': 400,
}

Dans le fichier settings.py

2. Dézip­per les fichiers

et placer le dossier scrapy_usera­gents dans votre projet (atten­tion j’ai bien dis scrapy_usera­gents et non scrapy-usera­gents).

3. Récu­pé­rer une liste de user-agent

Pour ma part, j’ai utili­ser les 10 derniers user-agent présent sur le site who is hosting this et copier les dans un fichier user-agents.txt que vous place­rez au même endroit que le dossier scrapy_usera­gents (et non pas dans ce dernier).

Rendre aléa­toire le délai entre deux requêtes

Toujours dans l’idée de passer inaperçu, et avec l’avan­tage de moins solli­ci­ter le serveur, je vous conseille de défi­nir un temps mini­mal entre chaque requête, pour ma part, j’ai choisi 750 milli­se­condes.

Dans la pratique, on réalise ceci en ajou­tant la ligne

DOWNLOAD_DELAY = 0.75

Dans le fichier settings.py

Oui bon là, je n’ai fait que défi­nir un laps de temps entre deux requêtes, mais alors comment faisons-nous pour avoir un délai aléa­toire ?

Réponse : nous ne faisons rien, par défaut Scrapy choi­sis un délai situé entre 0,5 et 1,5 DOWNLOAD_DELAY.

Suivre ou non les règles du fichier robots.txt

Selon le cas de figure, on pourra choi­sir d’ob­ser­ver ou d’igno­rer les règles du fichier robots.txt :

  • Si vous les igno­rer, vous verrez le site comme le voit un moteur de recherche.
  • Si vois les igno­rer, vous aurez un compor­te­ment plus proche de celui d’un visi­teur.

Encore une fois notre amis settings.py entre en jeux, il suffit de lui ajou­ter la ligne ci-dessous pour suivre les règles du robots.txt (par défaut, elles sont igno­rées) :

ROBOTSTXT_OBEY = True

Le spider

Le fichier nom_de_votre_projet.py dans le dossier spiders de votre projet va conte­nir :

  1. Le domaine à craw­ler et la page de départ ;
  2. Les fichiers auto­ri­sés et ceux qui ne le sont pas ;
  3. Les actions à effec­tuer pour chaque fichier trouvé.

Là aussi pour les détails, je vous renvoie à la docu­men­ta­tion de Scrapy et plus parti­cu­liè­re­ment la page sur les spiders.

Le résul­tat attendu

Pour chaque page

  • Code de réponse HTTP (200, 404, 500, etc.)
  • Temps de réponse
  • Descrip­tions mots-clefs et autre balises <méta>
  • Titre de la page (rien à voir avec les balises <h…>
  • Type mime
  • Titre de niveau 1 à 6
  • Contenu des balises <strong> et <em>
  • Liste de tous les mots de la page et leur fréquence

Pour chaque lien interne ou externe

  • Desti­na­tion (href)
  • Texte cliquable
  • Cible (target)
  • Rela­tion avec la cible (rel)
  • Titre

Pour chaque ancre

  • Nom
  • Texte

Pour chaque image

  • Source
  • Texte alter­na­tif
  • Titre
  • Largeur
  • Hauteur
  • Poids
  • Type du fichier
  • Type mime

Et tout ça dans un fichier CSV.

Pour aller plus loin :

  • Favi­con
  • Page­rank
  • Auteur / author rank
  • Télé­char­ger image
  • Temps de réponse
  • Recherche d’élé­ment pros­crit font, style en ligne, etc.
  • Recherche de struc­ture de liste mal formée.
  • Inter­ro­ger dmoz
  • rapport entre la taille des images et leur taille d’af­fi­chage dans le HTML.
  • CSS Javas­cript, nombre.

Récu­pé­ra­tion des données

La récu­pé­ra­tion des données s’ef­fec­tue à l’aide de Xpath comme je l’ai dit en début d’ar­ticle.

Xpath est une façon de navi­guer dans un docu­ment XML, ça fonc­tionne aussi dans un docu­ment HTML.

En gros, soit on four­nit un chemin pour sélec­tion­ner un objet précis type :

"/html/head/title/text()"

Pour sélec­tion­ner le titre de la page.

Soit on demande à récu­pé­rer tous les éléments parta­geant des carac­té­ris­tiques communes type :

"//a[@rel="follow"]"

Pour sélec­tion­ner tous les liens d’une page qui ont l’at­tri­but rel= »follow », ça fonc­tionne aussi avec les classes CSS.

Il n’y a plus qu’à faire cela pour tous les éléments sus-cités.

Bien entendu, il ne sera pas possible de récu­pé­rer tous les éléments de cette manière par exemple la taille ou le poids des images.

Les items

Le codes précé­dents à pour but d’ex­traire les données que nous souhai­tons conser­ver. Mais juste­ment, où les conce­vrons nous ?

Dans des items, il s’agit d’une spécia­lité de Scrapy. Celle-ci est bien pratique car comme nous le verrons ensuite, elle nous permet­tra d’ex­por­ter les données sous diffé­rents formats avec le moins de travail possible

L’ex­port

Comme je l’ai dit au début du chapitre précé­dent, Scrapy permet d’ex­por­ter les items dans diffé­rents formats :

  • Json
  • XML
  • CSV

 

 

Articles simi­laires :

Tagués avec : , , , , , , , , , ,

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée.

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.