Comment utiliser Python pour analyser les données SEO: un guide de référence – Gratuit : Audit complet de votre site internet

Avant de commencer !

Comment utiliser Python pour analyser les données SEO: un guide de référence
Share on facebook
Share on twitter
Share on pinterest

Vous trouvez-vous faire les mêmes tâches SEO répétitives chaque jour ou faire face à des défis où il n’y a pas d’outils qui peuvent vous aider?

Si c’est le cas, il est peut-être temps pour vous d’apprendre Python.

Un investissement initial de temps et de sueur portera ses fruits dans une productivité considérablement accrue.

Alors que j’écris cet article principalement pour les professionnels du référencement qui sont nouveaux dans la programmation, j’espère qu’il sera utile à ceux qui ont déjà une formation en logiciel ou en Python, mais qui recherchent une référence facile à analyser pour utilisation dans des projets d’analyse de données.

Table des matières

Fondamentaux Python

Python est facile à apprendre et je vous recommande de passer un après-midi à parcourir le didacticiel officiel. Je vais me concentrer sur les applications pratiques du référencement.

Lors de l’écriture de programmes Python, vous pouvez choisir entre Python 2 ou Python 3. Il est préférable d’écrire de nouveaux programmes en Python 3, mais il est possible que votre système soit livré avec Python 2 déjà installé, en particulier si vous utilisez un Mac. Veuillez également installer Python 3 pour pouvoir utiliser cette feuille de triche.

Vous pouvez vérifier votre version Python en utilisant:

$python --version

Utilisation d’environnements virtuels

Lorsque vous avez terminé votre travail, il est important de vous assurer que d’autres personnes de la communauté peuvent reproduire vos résultats. Ils devront être en mesure d’installer les mêmes bibliothèques tierces que vous utilisez, en utilisant souvent les mêmes versions exactes.

Python encourage la création d’environnements virtuels pour cela.

Si votre système est livré avec Python 2, veuillez télécharger et installer Python 3 à l’aide de la distribution Anaconda et exécutez ces étapes dans votre ligne de commande.

$sudo easy_install pip
$sudo pip install virtualenv
$mkdir seowork 
$virtualenv -p python3 seowork

Si vous utilisez déjà Python 3, veuillez exécuter ces étapes alternatives dans votre ligne de commande:

$mkdir seowork
$python3 -m venv seowork

Les étapes suivantes permettent de travailler dans n’importe quelle version de Python et vous permettent d’utiliser les environnements virtuels.

$cd seowork
$source bin/activate
(seowork)$deactivate

Lorsque vous désactivez l’environnement, vous revenez à votre ligne de commande et les bibliothèques que vous avez installées dans l’environnement ne fonctionneront pas.

Bibliothèques utiles pour l’analyse des données

Chaque fois que je démarre un projet d’analyse de données, j’aime avoir au minimum les bibliothèques suivantes installées:

La plupart d’entre eux sont inclus dans la distribution Anaconda. Ajoutons-les à notre environnement virtuel.

(seowork)$pip3 install requests
(seowork)$pip3 install matplotlib
(seowork)$pip3 install requests-html
(seowork)$pip3 install pandas

Vous pouvez les importer au début de votre code comme ceci:

import requests
from requests_html import HTMLSession
import pandas as pd

Comme vous avez besoin de plus de bibliothèques tierces dans vos programmes, vous avez besoin d’un moyen simple de les suivre et d’aider les autres à configurer facilement vos scripts.

Vous pouvez exporter toutes les bibliothèques (et leurs numéros de version) installées dans votre environnement virtuel en utilisant:

(seowork)$pip3 freeze > requirements.txt

Lorsque vous partagez ce fichier avec votre projet, toute autre personne de la communauté peut installer toutes les bibliothèques requises à l’aide de cette simple commande dans son propre environnement virtuel:

(peer-seowork)$pip3 install -r requirements.txt

Utilisation des ordinateurs portables Jupyter

Lors de l’analyse des données, je préfère utiliser les blocs-notes Jupyter car ils fournissent un environnement plus pratique que la ligne de commande. Vous pouvez inspecter les données avec lesquelles vous travaillez et écrire vos programmes de manière exploratoire.

(seowork)$pip3 install jupyter

Ensuite, vous pouvez exécuter le bloc-notes en utilisant:

(seowork)$jupyter notebook

Vous obtiendrez l’URL à ouvrir dans votre navigateur.

Alternativement, vous pouvez utiliser Google Colaboratory qui fait partie de GoogleDocs et ne nécessite aucune configuration.

Formatage des chaînes

Vous passerez beaucoup de temps dans vos programmes à préparer des chaînes pour l’entrée dans différentes fonctions. Parfois, vous devez combiner des données de différentes sources ou convertir d’un format à un autre.

Supposons que vous souhaitiez extraire par programme des données Google Analytics. Vous pouvez créer une URL d’API à l’aide de l’explorateur de requêtes Google Analytics et remplacer les valeurs des paramètres de l’API par des espaces réservés à l’aide de crochets. Par exemple:

api_uri = "https://www.googleapis.com/analytics/v3/data/ga?ids={gaid}&"
 "start-date={start}&end-date={end}&metrics={metrics}&"
 "dimensions={dimensions}&segment={segment}&access_token={token}&"
 "max-results={max_results}"

{gaid} est le compte Google, c’est-à-dire « ga: 12345678 »

{start} est la date de début, c’est-à-dire « 2017-06-01 »

{end} est la date de fin, c’est-à-dire « 2018-06-30 »

{metrics} correspond à la liste des paramètres numériques, c’est-à-dire « ga: users », « ga: newUsers »

{dimensions} est la liste des paramètres catégoriels, c’est-à-dire « ga: landingPagePath », « ga: date »

{segment} correspond aux segments marketing. Pour le référencement, nous voulons la recherche organique, qui est «gaid :: – 5»

{token} est le jeton d’accès de sécurité que vous obtenez de Google Analytics Query Explorer. Il expire après une heure et vous devez réexécuter la requête (pendant l’authentification) pour en obtenir une nouvelle.

{max_results} est le nombre maximum de résultats pour récupérer jusqu’à 10 000 lignes.

Vous pouvez définir des variables Python pour contenir tous ces paramètres. Par exemple:

gaid = "ga:12345678"
start = "2017-06-01"
end = "2018-06-30"

Cela vous permet de récupérer assez facilement les données de plusieurs sites Web ou plages de données.

Enfin, vous pouvez combiner les paramètres avec l’URL de l’API pour produire une demande d’API valide à appeler.

api_uri = api_uri.format(
 gaid=gaid,
 start=start,
 end=end,
 metrics=metrics,
 dimensions=dimensions,
 segment=segment,
 token=token,
 max_results=max_results
 )

Python remplacera chaque espace réservé par sa valeur correspondante parmi les variables que nous transmettons.

Encodage de chaîne

L’encodage est une autre technique courante de manipulation de chaînes. De nombreuses API nécessitent des chaînes formatées d’une certaine manière.

Par exemple, si l’un de vos paramètres est une URL absolue, vous devez l’encoder avant de l’insérer dans la chaîne API avec des espaces réservés.

from urllib import parse
url="https://www.searchenginejournal.com/"
parse.quote(url)

La sortie ressemblera à ceci: «Https% 3A // www.searchenginejournal.com /» qui serait sûr à passer à une demande d’API.

Autre exemple: supposons que vous souhaitiez générer des balises de titre comprenant une esperluette (&) ou des crochets angulaires (<, >). Ceux-ci doivent être échappés pour éviter de confondre les analyseurs HTML.

import html
title= "SEO "
html.escape(title)

La sortie ressemblera à ceci:

'SEO <News & Tutorials>'

De même, si vous lisez des données encodées, vous pouvez les rétablir.

html.unescape(escaped_title)

La sortie sera relue comme l’original.

Formatage de la date

Il est très courant d’analyser des données de séries chronologiques, et les valeurs d’horodatage de la date et de l’heure peuvent prendre de nombreux formats différents. Python prend en charge la conversion des dates en chaînes et inversement.

Par exemple, après avoir obtenu les résultats de l’API Google Analytics, nous pourrions vouloir analyser les dates en objets datetime. Cela facilitera leur tri ou leur conversion d’un format de chaîne à un autre.

from datetime import datetime
dt = datetime.strptime('Jan 5 2018 6:33PM', '%b %d %Y %I:%M%p')

Ici% b,% d, etc. sont des directives supportées par strptime (utilisé lors de la lecture des dates) et strftime (utilisé lors de leur écriture). Vous pouvez trouver la référence complète ici.

Faire des demandes d’API

Maintenant que nous savons comment formater les chaînes et créer des requêtes API correctes, voyons comment nous effectuons réellement de telles requêtes.

r = requests.get(api_uri)

Nous pouvons vérifier la réponse pour nous assurer que nous avons des données valides.

print(r.status_code)
print(r.headers['content-type'])

Vous devriez voir un code d’état 200. Le type de contenu de la plupart des API est généralement JSON.

Lorsque vous vérifiez les chaînes de redirection, vous pouvez utiliser le paramètre d’historique de redirection pour voir la chaîne complète.

print(r.history)

Afin d’obtenir l’URL finale, utilisez:

print(r.url)

Une grande partie de votre travail consiste à obtenir les données dont vous avez besoin pour effectuer votre analyse. Les données seront disponibles à partir de différentes sources et formats. Explorons les plus courants.

Lecture de JSON

La plupart des API renvoient des résultats au format JSON. Nous devons analyser les données dans ce format dans des dictionnaires Python. Pour ce faire, vous pouvez utiliser la bibliothèque JSON standard.

import json
json_response = '{"website_name": "Search Engine Journal", "website_url":"https://www.searchenginejournal.com/"}'
parsed_response = json.loads(json_response)

Vous pouvez désormais accéder facilement à toutes les données dont vous avez besoin. Par exemple:

print(parsed_response["website_name"])

La sortie serait:

"Search Engine Journal"

Lorsque vous utilisez la bibliothèque de demandes pour effectuer des appels d’API, vous n’avez pas besoin de le faire. L’objet de réponse fournit une propriété pratique pour cela.

parsed_response=r.json()

Lecture à partir de pages HTML

La plupart des données dont nous avons besoin pour le référencement seront sur les sites Web des clients. Bien qu’il ne manque pas de formidables robots de référencement, il est important d’apprendre à vous explorer pour faire des trucs fantaisistes comme le regroupement automatique des pages par type de page.

from requests_html import HTMLSession
session = HTMLSession()
r = session.get('https://www.searchenginejournal.com/')

Vous pouvez obtenir tous les liens absolus en utilisant ceci:

print(r.html.absolute_links)

La sortie partielle ressemblerait à ceci:

 {'http://jobs.searchenginejournal.com/', 'https://www.searchenginejournal.com/what-i-learned-about-seo-this-year/281301/', …}

Ensuite, récupérons quelques balises SEO courantes à l’aide de XPATH:

Titre de la page

r.html.xpath('//title/text()') 

La sortie est:

['Search Engine Journal - SEO, Search Marketing News and Tutorials']

Meta Description

r.html.xpath("//meta[@name='description']/@content")

Veuillez noter que j’ai changé le style des guillemets de simple à double ou j’obtiendrais une erreur de codage.

La sortie est:

['Search Engine Journal is dedicated to producing the latest search news, the best guides and how-tos for the SEO and marketer community.']

Canonique

r.html.xpath("//link[@rel='canonical']/@href")

La sortie est:

 ['https://www.searchenginejournal.com/']

URL AMP

r.html.xpath("//link[@rel='amphtml']/@href")

Le Journal des moteurs de recherche n’a pas d’URL AMP.

Meta Robots

r.html.xpath("//meta[@name='ROBOTS']/@content")

La sortie est:

['NOODP']

H1s

r.html.xpath("//h1")

La page d’accueil du Journal des moteurs de recherche ne contient pas de fichiers h1.

Valeurs d’attribut HREFLANG

r.html.xpath("//link[@rel='alternate']/@hreflang")

Le Journal des moteurs de recherche n’a pas d’attributs hreflang.

Vérification du site Google

r.html.xpath("//meta[@name='google-site-verification']/@content")

La sortie est:

['NcZlh5TFoRGYNheLXgxcx9gbVcKCsHDFnrRyEUkQswY',
 'd0L0giSu_RtW_hg8i6GRzu68N3d4e7nmPlZNA9sCc5s',
 'S-Orml3wOAaAplwsb19igpEZzRibTtnctYrg46pGTzA']

Rendu JavaScript

Si la page que vous analysez nécessite un rendu JavaScript, il vous suffit d’ajouter une ligne de code supplémentaire pour le prendre en charge.

from requests_html import HTMLSession
session = HTMLSession()
r = session.get('https://www.searchenginejournal.com/')
r.html.render()

La première fois que vous exécutez render () prendra un certain temps car Chromium sera téléchargé. Le rendu de Javascript est beaucoup plus lent que sans rendu.

Lecture des demandes XHR

Comme le rendu de JavaScript est lent et prend du temps, vous pouvez utiliser cette approche alternative pour les sites Web qui chargent du contenu JavaScript à l’aide de requêtes AJAX.

Capture d'écran montrant comment vérifier les en-têtes de demande d'un fichier JSON à l'aide des outils Chrome Developer. Le chemin du fichier json est mis en surbrillance, tout comme l'en-tête x-required-with. Capture d’écran montrant comment vérifier les en-têtes de demande d’un fichier JSON à l’aide des outils Chrome Developer. Le chemin du fichier JSON est mis en évidence, tout comme l’en-tête x-required-with.
ajax_request='https://www.searchenginejournal.com/location.json'
r = requests.get(ajax_request)
results=r.json()

Vous obtiendrez plus rapidement les données dont vous avez besoin car il n’y a pas de rendu JavaScript ni même d’analyse HTML.

Lecture à partir des journaux du serveur

Google Analytics est puissant, mais n’enregistre ni ne présente les visites de la plupart des robots des moteurs de recherche. Nous pouvons obtenir ces informations directement à partir des fichiers journaux du serveur.

Voyons comment analyser les fichiers journaux du serveur à l’aide d’expressions régulières en Python. Vous pouvez vérifier l’expression régulière que j’utilise ici.

import re
log_line='66.249.66.1 - - [06/Jan/2019:14:04:19 +0200] "GET / HTTP/1.1" 200 - "" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"'
regex='([(d.)]+) - - [(.*?)] "(.*?)" (d+) - "(.*?)" "(.*?)"'
groups=re.match(regex, line).groups()
print(groups)

La sortie décompose joliment chaque élément de l’entrée de journal:

('66.249.66.1', '06/Jan/2019:14:04:19 +0200', 'GET / HTTP/1.1', '200', '', 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)')

Vous accédez à la chaîne d’agent utilisateur dans le groupe six, mais les listes en Python commencent à zéro, c’est donc cinq.

print(groups[5])

La sortie est:

'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'

Vous pouvez en apprendre davantage sur l’expression régulière en Python ici. Assurez-vous de vérifier la section sur les expressions gourmandes et non gourmandes. J’utilise non gourmand lors de la création des groupes.

Vérification de Googlebot

Lors de l’analyse des journaux pour comprendre le comportement des robots de recherche, il est important d’exclure toutes les fausses demandes, car tout le monde peut prétendre être Googlebot en modifiant la chaîne de l’agent utilisateur.

Google propose une approche simple pour ce faire ici. Voyons comment l’automatiser avec Python.

import socket
bot_ip = "66.249.66.1"
host = socket.gethostbyaddr(bot_ip)
print(host[0])

Tu auras crawl-66-249-66-1.googlebot.com

ip = socket.gethostbyname(host[0])

Vous obtenez «66 .249.66.1», ce qui montre que nous avons une véritable IP Googlebot car elle correspond à notre IP d’origine que nous avons extraite du journal du serveur.

Lecture à partir d’URL

Les URL des pages Web sont une source d’informations souvent négligée. La plupart des sites Web et des systèmes de gestion de contenu incluent des informations riches dans les URL. Voyons comment extraire cela.

Il est possible de décomposer des URL en leurs composants à l’aide d’expressions régulières, mais il est beaucoup plus simple et robuste d’utiliser la bibliothèque standard urllib pour ça.

from urllib.parse import urlparse
url="https://www.searchenginejournal.com/?s=google&search-orderby=relevance&searchfilter=0&search-date-from=January+1%2C+2016&search-date-to=January+7%2C+2019"
parsed_url=urlparse(url)
print(parsed_url)

La sortie est:

ParseResult(scheme='https', netloc='www.searchenginejournal.com', path='/', params='', query='s=google&search-orderby=relevance&searchfilter=0&search-date-from=January+1%2C+2016&search-date-to=January+7%2C+2019', fragment='')

Par exemple, vous pouvez facilement obtenir le nom de domaine et le chemin du répertoire en utilisant:

print(parsed_url.netloc)
print(parsed_url.path)

Cela produirait ce que vous attendez.

Nous pouvons en outre décomposer la chaîne de requête pour obtenir les paramètres d’URL et leurs valeurs.

parsed_query=parse_qs(parsed_url.query)
print(parsed_query)

Vous obtenez un dictionnaire Python en sortie.

{'s': ['google'],
 'search-date-from': ['January 1, 2016'],
 'search-date-to': ['January 7, 2019'],
 'search-orderby': ['relevance'],
 'searchfilter': ['0']}

Nous pouvons continuer et analyser les chaînes de date dans des objets datetime Python, ce qui vous permettrait d’effectuer des opérations de date comme le calcul du nombre de jours entre la plage. Je vais laisser cela comme un exercice pour vous.

Une autre technique courante à utiliser dans votre analyse consiste à casser la partie chemin de l’URL par «/» pour obtenir les parties. C’est simple à faire avec la fonction split.

url="https://www.searchenginejournal.com/category/digital-experience/"
parsed_url=urlparse(url)
parsed_url.path.split("/")

La sortie serait:

 ['', 'category', 'digital-experience', '']

Lorsque vous divisez les chemins d’URL de cette façon, vous pouvez l’utiliser pour regrouper un grand groupe d’URL par leurs répertoires supérieurs.

Par exemple, vous pouvez trouver tous les produits et toutes les catégories sur un site Web de commerce électronique lorsque la structure URL le permet.

Exécution d’une analyse de base

Vous passerez la plupart de votre temps à obtenir les données dans le bon format pour l’analyse. La partie analyse est relativement simple, à condition que vous connaissiez les bonnes questions à poser.

Commençons par charger une analyse Screaming Frog dans une trame de données pandas.

import pandas as pd
df = pd.DataFrame(pd.read_csv('internal_all.csv', header=1, parse_dates=['Last Modified']))
print(df.dtypes)

La sortie affiche toutes les colonnes disponibles dans le fichier Screaming Frog et leurs types Python. J’ai demandé aux pandas d’analyser la colonne Last Modified dans un objet datetime Python.

Réalisons quelques exemples d’analyses.

Regroupement par répertoire de premier niveau

Commençons par créer une nouvelle colonne avec le type de pages en divisant le chemin des URL et en extrayant le premier nom de répertoire.

df['Page Type']=df['Address'].apply(lambda x: urlparse(x).path.split("/")[1])
aggregated_df=df[['Page Type','Word Count']].groupby(['Page Type']).agg('sum')
print(aggregated_df)

Après avoir créé la colonne Type de page, nous regroupons toutes les pages par type et par total le nombre de mots. La sortie ressemble partiellement à ceci:

seo-guide 736
seo-internal-links-best-practices 2012
seo-keyword-audit 2104
seo-risks 2435
seo-tools 588
seo-trends 3448
seo-trends-2019 2676
seo-value 1528

Regroupement par code d’état

status_code_df=df[['Status Code', 'Address']].groupby(['Status Code']).agg('count')
print(status_code_df)

200 218
301 6
302 5

Liste des redirections temporaires

temp_redirects_df=df[df['Status Code'] == 302]['Address']
print(temp_redirects_df)

50 https://www.searchenginejournal.com/wp-content...
116 https://www.searchenginejournal.com/wp-content...
128 https://www.searchenginejournal.com/feed
154 https://www.searchenginejournal.com/wp-content...
206 https://www.searchenginejournal.com/wp-content...

Liste des pages sans contenu

no_content_df=df[(df['Status Code'] == 200) & (df['Word Count'] == 0 ) ][['Address','Word Count']]

7 https://www.searchenginejournal.com/author/cor... 0
9 https://www.searchenginejournal.com/author/vic... 0
66 https://www.searchenginejournal.com/author/ada... 0
70 https://www.searchenginejournal.com/author/ron... 0

Activité de publication

Voyons à quels moments de la journée le plus d’articles sont publiés dans SEJ.

lastmod = pd.DatetimeIndex(df['Last Modified'])
writing_activity_df=df.groupby([lastmod.hour])['Address'].count()

0.0 19
1.0 55
2.0 29
10.0 10
11.0 54
18.0 7
19.0 31
20.0 9
21.0 1
22.0 3

Il est intéressant de voir qu’il n’y a pas beaucoup de changements pendant les heures normales de travail.

Nous pouvons tracer cela directement à partir des pandas.

writing_activity_df.plot.bar()
Diagramme à barres montrant les heures de la journée où les articles sont publiés dans le Search Engine Journal. Le graphique à barres a été généré à l'aide de Python 3. Diagramme à barres montrant les heures de la journée où les articles sont publiés dans le Search Engine Journal. Le graphique à barres a été généré à l’aide de Python 3.

Enregistrement et exportation des résultats

Maintenant, nous arrivons à la partie la plus simple: sauvegarder les résultats de notre travail acharné.

Enregistrement dans Excel

writer = pd.ExcelWriter(no_content.xlsx')
no_content_df.to_excel(writer,'Results')
writer.save()

Enregistrement au format CSV

temporary_redirects_df.to_csv('temporary_redirects.csv')

Ressources supplémentaires pour en savoir plus

Nous avons à peine effleuré la surface de ce qui est possible lorsque vous ajoutez des scripts Python à votre travail de référencement quotidien. Voici quelques liens à explorer davantage.

Davantage de ressources:


Crédits d’image

Capture d’écran prise par l’auteur, janvier 2019
Diagramme à barres généré par l’auteur, janvier 2019

Inscris-toi à notre newsletter !

Partage cet article avec tes amis !

Share on facebook
Share on google
Share on twitter
Share on linkedin