Qu’est-ce que la courbe CTR et comment la calculer avec Python ?

22 mars 2022 - 18  min de lecture - par Alireza Esmikhani
Accueil > SEO Technique > Comment calculer le CTR organique avec Python?

La courbe CTR, ou le taux de clic organique basé sur la position, est une donnée qui vous montre combien de liens bleus dans la Search Engine Result Page (SERP) obtiennent un CTR en fonction de leur position. Par exemple, la plupart du temps, le premier lien bleu dans la SERP obtient le plus de CTR.

À la fin de ce tutoriel, vous serez capable de calculer la courbe du CTR de votre site basé sur ses répertoires, ou calculer le CTR organique en fonction du CTR des requêtes. Le résultat de mon code Python est un diagramme en boîte et en barre pour décrire la courbe du CTR d’un site.

Courbe CTR avec Python

Si vous êtes un débutant et que vous n’êtes pas familier avec la définition du CTR, je vous l’expliquerai plus en détails dans la section suivante.

Qu’est-ce que le CTR organique ou le taux de clic organique ?

Le CTR est calculé en divisant les clics organiques par les impressions. Par exemple, si 100 personnes lancent une recherche du mot « pomme » et que 30 personnes cliquent sur le premier résultat, le CTR du premier résultat est de 30 / 100 * 100 = 30%.

Cela signifie que sur 100 recherches, vous obtenez 30 % d’entre elles. Il faut savoir que les impressions dans Google Search Console (GSC) ne sont pas basées sur l’apparition du lien de votre site Web dans la fenêtre de l’utilisateur. Ils sont pris en compte si seulement le résultat apparaît dans la SERP de l’utilisateur ; vous obtenez une impression pour chacune des recherches.

Quels sont les cas d’utilisation de la courbe CTR ?

L’un des sujets le plus important en matière de SEO est la prévision du trafic organique. Pour améliorer votre classement pour un certain ensemble de mots-clés, vous devez allouer des milliers et des milliers de dollars pour obtenir plus d’actions. La question qui se pose au niveau marketing est la suivante : « Est-ce rentable d’allouer autant de budget ? ».

De plus, à part les questions budgétaires pour des projets SEO, il faut estimer la hausse ou la baisse éventuelle de votre trafic organique dans l’avenir. Par exemple, si vous voyez l’un de vos concurrents qui essaie de vous remplacer dans les SERPs, combien cela vous coûtera-t-il ?

Dans cette situation ou dans plein d’autres, vous auriez besoin de la courbe CTR de votre site pour trouver une réponse.

Pourquoi ne pas utiliser les études sur les courbes CTR et utiliser vos données ?

Si je souhaite répondre simplement, il n’y a pas d’autre site Web qui a les caractéristiques de votre site dans les SERPs.

Il existe beaucoup d’études sur les courbes de CTR dans différents secteurs et différentes caractéristiques de SERP. Mais lorsque vous disposez de vos données, pourquoi vos sites ne calculent-ils pas le CTR plutôt que de s’appuyer sur des sources tierces ?

Nous allons voir cela ensemble.

Calculer la courbe CTR avec Python : le début

Avant de commencer à calculer le taux de clics de Google sur le site en fonction de la position, vous devez bien comprendre la syntaxe de base de Python et aussi avoir une connaissance de base des bibliothèques Python courantes, comme Pandas. Cela vous aidera à mieux comprendre le code, et à le personnaliser à votre façon.

Je préfère utiliser un carnet comme Jupyter pour ce processus.

Afin de calculer le CTR organique en fonction de la position, nous utiliserons les bibliothèques Python ci-dessous :

  • Pandas
  • Plotly
  • Kaleido

Nous utiliserons également ces bibliothèques standard Python :

  • os
  • json

Comme déjà évoqué, nous explorons deux manières différentes de calculer la courbe CTR. Certaines étapes sont les mêmes dans les deux cas : l’importation des packages Python, la création du dossier de résultat pour les diagrammes et la définition de leurs tailles.

# Importing needed libraries for our process
import os
import json
import pandas as pd
import plotly.express as px
import plotly.io as pio
import kaleido

Ici, nous créons un dossier pour sauvegarder nos images.

# Creating plot images output folder
if not os.path.exists('./output plot images'):
    os.mkdir('./output plot images')

Vous pouvez modifier la hauteur et la largeur des images comme ci-dessous.

# Setting width and height of the output plot images
pio.kaleido.scope.default_height = 800
pio.kaleido.scope.default_width = 2000

Commençons par la première méthode basée sur le CTR des requêtes.

Première méthode : Calculer la courbe du CTR pour l’ensemble du site Web ou pour une propriété URL spécifique en fonction du CTR des requêtes.

Premièrement, nous récupérons toutes nos requêtes avec leur CTR, leur position moyenne et leur impression. Je préfère un mois de données complètes du mois précédent.

Afin de le faire, je récupère les données des requêtes de la source de données impression du site GSC dans Google Data Studio.

Vous pouvez également obtenir ces données d’une autre manière à votre préférence, comme l’API GSC ou l’extension Google Analytics for Sheets.

De cette façon, si votre blog ou vos pages de produits ont une propriété URL dédiée, vous pouvez les utiliser comme source de données dans GDS.

1. Obtenir des données de requêtes de Google Data Studio (GDS)

Pour le faire :

  1. Créez un rapport et ajoutez-y un tableau graphique
  2. Ajoutez la source de données « Impression du site » de votre site dans le rapport
  3. Choisissez « query » pour la dimension et « ctr », « average position » et « ‘impression » pour la métrique
  4. Filtrez les requêtes qui contiennent le nom de la marque en créant un filtre (les requêtes contenant des marques auront un taux de clics plus élevé, ce qui diminuera la précision de nos données)
  5. Faites un clic-droit sur le tableau et sélectionnez « Exporter »
  6. Sauvegardez les données en format CSV

Queries data GDS

2. Charger vos données et étiqueter les requêtes en fonction de leur position

Pour manipuler le fichier CSV téléchargé, nous utilisons Pandas.

La meilleure méthode pour structurer votre travail est de créer un dossier ‘data’ et d’y placer toutes vos données.

Ici, pour rendre plus fluide le tutoriel, je ne l’ai pas fait.

query_df = pd.read_csv('./downloaded_data.csv')

Ensuite, nous étiquetons nos requêtes en fonction de leur position. J’ai créé une boucle pour étiqueter les positions 1 à 10.

Par exemple, si la position moyenne d’une requête est 2,2 ou 2,9, elle sera étiquetée « 2 ». En manipulant la plage de position moyenne, vous pouvez obtenir la précision souhaitée.

for i in range(1, 11):
    query_df.loc[(query_df['Average Position'] >= i) & (
        query_df['Average Position'] < i + 1), 'position label'] = i

Maintenant, nous regroupons les requêtes en fonction de leur position. Cela vous aidera à manipuler les données de chaque requête de position plus efficacement dans les étapes suivantes.

query_grouped_df = query_df.groupby(['position label'])

3. Filtrage des requêtes en fonction de leurs données pour le calcul de la courbe de CTR

La façon la plus simple de calculer la courbe CTR est d’utiliser toutes les données des requêtes et de faire le calcul. Mais il ne faut pas oublier les requêtes avec 1 impression en position 2 dans vos données.

D’après mon expérience, ces requêtes peuvent faire une grande différence dans le résultat final. Le mieux est de l’essayer vous-même. En fonction de l’ensemble des données, cela peut changer.

Avant de commencer cette étape, vous devez créer une liste pour le résultat de votre diagramme à barres et un DataFrame pour stocker vos requêtes manipulées.

# Creating a DataFrame for storing 'query_df' manipulated data
modified_df = pd.DataFrame()

# A list for saving each position mean for our bar chart
mean_ctr_list = []

Ensuite, nous allons boucler sur les groupes « query_grouped_df » et après ajouter les 20% de requêtes les plus importantes basées sur les impressions au DataFrame « modified_df ».

Si le calcul du CTR sur la base des 20% de requêtes avec les plus d’impressions ne vous semble pas optimal, n’hésitez pas à le modifier.

Pour le modifier, vous pouvez l’augmenter ou le diminuer avec le code : .quantile(q=your_optimal_number, interpolation='lower')]. and you_optimal_number doit être entre 0 et 1.

Par exemple, si vous souhaitez obtenir le top 30 % de vos requêtes, your_optimal_num est la différence entre 1 et ‌0,3 (soit 0,7).

for i in range(1, 11):
        # A try-except for handling those situations that a directory hasn't any data for some positions
        try:
            tmp_df = query_grouped_df.get_group(i)[query_grouped_df.get_group(i)['impressions'] >= query_grouped_df.get_group(i)['impressions']
                                                 .quantile(q=0.8, interpolation='lower')]
            mean_ctr_list.append(tmp_df['ctr'].mean())
            modified_df = modified_df.append(tmp_df, ignore_index=True)
        except KeyError:
            mean_ctr_list.append(0)

# Deleting 'tmp_df' DataFrame for reducing memory usage
del [tmp_df]

4. Dessiner un diagramme en boîte

Pour dessiner un diagramme, vous pouvez utiliser Matplotlib, seaborn en tant que wrapper pour Matplotlib, ou Plotly.

Je pense personnellement que Plotly est l’une des meilleures solutions pour les spécialistes du marketing qui aiment explorer les données.

Par rapport à Mathplotlib, Plotly est très facile à utiliser et, avec quelques lignes de code, vous pouvez créer un beau graphique.

# 1. The box plot
box_fig = px.box(modified_df, x='position label', y='Site CTR', title='Queries CTR distribution based on position',
             points='all', color='position label', labels={'position label': 'Position', 'Site CTR': 'CTR'})

# Showing all ten x-axes ticks
box_fig.update_xaxes(tickvals=[i for i in range(1, 11)])

# Changing the y-axes tick format to percentage
box_fig.update_yaxes(tickformat=".0%")

# Saving plot to 'output plot images' directory
box_fig.write_image('./output plot images/Queries box plot CTR curve.png')

Avec ces quatre lignes, vous pouvez obtenir un très beau diagramme en boîte et commencer à explorer vos données.

Courbe CTR Python_diagramme en boîte

Si vous souhaitez manipuler cette colonne, dans une nouvelle cellule, tapez :

box_fig.show()

Maintenant, vous avez un diagramme en boîte interactive.

Lorsque vous survolez un graphique interactif, le chiffre important à regarder est le « man » de chaque position : cela montre le CTR moyen pour chaque position.

Grâce à l’importance de la moyenne, vous pouvez créer une liste qui contient les moyennes de chaque position.

Nous passons maintenant à l’étape suivante pour dessiner un diagramme à barres basé sur la moyenne de chaque position.

5. Dessiner un diagramme à barres

Comme pour le diagramme en boîte, dessiner un diagramme à barres est aussi très facile. Vous pouvez changer le title des graphiques en modifiant l’argument title de la fonction px.bar().

# 2. The bar plot
bar_fig = px.bar(x=[pos for pos in range(1, 11)], y=mean_ctr_list, title='Queries mean CTR distribution based on position',
              labels={'x': 'Position', 'y': 'CTR'}, text_auto=True)

# Showing all ten x-axes ticks
bar_fig.update_xaxes(tickvals=[i for i in range(1, 11)])

# Changing the y-axes tick format to percentage
bar_fig.update_yaxes(tickformat='.0%')

# Saving plot to 'output plot images' directory
bar_fig.write_image('./output plot images/Queries bar plot CTR curve.png')

Vous obtenez ce graphique comme résultat :

Courbe CTR Python_diagramme à barres

Comme avec le diagramme en boîte, vous pouvez manipuler le graphique avec la commande : bar_fig.show().

Et c’est tout. Avec quelques lignes de code, vous avez réussi à générer le taux de clic organique basé sur la position avec les données de vos requêtes.

Si vous disposez d’une propriété URL pour chacun de vos sous-domaines ou répertoires, vous pouvez obtenir les requêtes de ces propriétés URL et calculer leur propres courbes CTR.

[Étude de cas] Améliorer les classements, visites organiques et ventes avec l’analyse des fichiers de log

Au début de l’année 2017, l’équipe de TutorFair.com a sollicité les services SEO d’Omi Sido pour les aider. Leur site web luttait avec ses classements et visites organiques.

Deuxième méthode : Calculer la courbe du CTR en fonction de l’URL des landing pages pour chaque répertoire

Avec la première méthode, nous avons calculé le CTR organique en nous basant sur le CTR des requêtes, mais avec cette deuxième méthode, nous récupérons plutôt toutes les données de nos landing pages et nous calculons ensuite la courbe du CTR pour les répertoires sélectionnés.

J’adore cette méthode. Comme vous le savez, le CTR de vos pages de produits est très différent de celui de vos articles de blog ou d’autres pages. Chaque répertoire a son propre CTR basé sur la position.

De manière plus avancée, vous pouvez catégoriser chaque page du répertoire et obtenir le taux de clics organique de Google en fonction de la position d’un ensemble de pages.

1. Obtenir les données de vos landing pages

Il existe plusieurs façons d’obtenir les données de Google Search Console (GSC). Dans ce cas, j’e préfére obtenir les données des landing pages à partir de l’API GSC à l’adresse suivante : https://developers.google.com/webmaster-tools/v1/searchanalytics/query

Dans ce cas, le GDS ne fournit pas de données fiables sur les landing pages. Vous pouvez à nouveau utiliser l’extension ‘Search Analytics for Sheets’ de Google Sheets.

Le Google API Explorer convient bien aux sites dont les données sont inférieures à 25 000 pages. Pour les sites plus importants, il existe d’autres options : vous pouvez obtenir partiellement les données des landing pages et les concaténer ensemble, écrire un script Python avec une boucle ‘for’ pour obtenir toutes vos données de GSC, ou même utiliser des outils tiers.

Pour obtenir des données à partir de Google API Explorer :

  1. Accédez à la page de documentation de l’API GSC « Search Analytics : query » : https://developers.google.com/webmaster-tools/v1/searchanalytics/query.
  2. Utilisez l’explorateur d’API qui se trouve sur le côté droit de la page
  3. Dans le champ « siteUrl », insérez l’adresse de votre propriété URL, comme ci-dessous : https://www.example.com. Vous pouvez également insérer la propriété de votre domaine comme cela : sc-domain:example.com
  4. Dans le champ « request body » ajoutez startDate et endDate. Je préfère obtenir les données du mois dernier. Le format de ces valeurs est YYYY-MM-DD
  5. Ajoutez "dimension" et définissez ses valeurs comme page
  6. Créez « dimensionFilterGroups » et filtrez les requêtes contenant des variantes de noms de marque (en remplaçant brand_variation_names par vos noms de marque RegExp)
  7. Ajoutez rawLimit et le fixer à 25000
  8. À la fin, appuyez sur le bouton ‘EXECUTE’

Vous pouvez également copier et coller la demande ci-dessous :

{
  "startDate": "2022-01-01",
  "endDate": "2022-02-01",
  "dimensions": [
    "page"
  ],
  "dimensionFilterGroups": [
    {
      "filters": [
        {
          "dimension": "QUERY",
          "expression": "brand_variation_names",
          "operator": "EXCLUDING_REGEX"
        }
      ]
    }
  ],
  "rowLimit": 25000
}

Google API Interface

Une fois la requête exécutée, enregistrez-la. En raison du format de la réponse, vous aurez besoin de créer un fichier JSON, copier toutes les réponses JSON et l’enregistrer avec le nom de fichier downloaded_data.json.

Si votre site est petit, tel un site d’entreprise SASS, et les données de votre landing page sont inférieures à 1 000 pages, vous pouvez facilement définir votre date dans GSC et exporter les données de l’onglet « PAGES » sous forme de fichier CSV.

GSC Performance Search Results

2. Chargement des données des landing pages

Supposons, pour cet exemple, que vous obteniez des données de Google API Explorer et que vous les enregistriez dans un fichier JSON.

Pour charger ces données, vous devez exécuter le code ci-dessous.

# Creating a DataFrame for the downloaded data
with open('./downloaded_data.json') as json_file:
    landings_data = json.loads(json_file.read())['rows']
    landings_df = pd.DataFrame(landings_data)

Il faut aussi changer le nom d’une colonne pour lui donner plus de sens et appliquer une fonction pour obtenir les URLs des landing pages directement dans la colonne « landing page ».

# Renaming 'keys' column to 'landing page' column and converting 'landing page' list to an URL
landings_df.rename(columns={'keys': 'landing page'}, inplace=True)
landings_df['landing page'] = landings_df['landing page'].apply(lambda x: x[0])

3. Récupérer les répertoires racines de toutes les landing pages

Tout d’abord, il faut définir le nom de votre site.

# Defining your site name between quotes. For example, 'https://www.example.com/' or 'http://mydomain.com/'
site_name = ''

Ensuite, exécutez une fonction sur les URLs des landing pages afin de trouver leurs répertoires racines et les retrouver dans les résultats.

# Getting each landing page (URL) directory
landings_df['directory'] = landings_df['landing page'].str.extract(pat=f'((?<={site_name})[^/]+)')

# For getting all directories in the output, we need to manipulate Pandas options
pd.set_option("display.max_rows", None)

# Website directories
landings_df['directory'].value_counts()

Puis, choisissez les répertoires dont vous avez besoin pour calculer leur courbe de CTR.

Insérez les répertoires dans la variable important_directories

Par exemple, product,tag,product-category,mag. Séparez les valeurs du répertoire par une virgule.

important_directories = ''
important_directories = important_directories.split(',')

4. Étiquetage et regroupement des landing pages

Comme pour les requêtes, il faut étiqueter les landing pages en fonction de leur position moyenne.

# Labeling landing pages position
for i in range(1, 11):
    landings_df.loc[(landings_df['position'] >= i) & (
        landings_df['position'] < i + 1), 'position label'] = i

Après, regroupez les landing pages en fonction de leur « directory ».

# Grouping landing pages based on their 'directory' value
landings_grouped_df = landings_df.groupby(['directory'])

5. Générer des diagrammes en boîte et à barres pour vos répertoires

Dans la méthode précédente, nous n’avons pas utilisé une fonction pour générer les diagrammes. Cependant, pour calculer automatiquement la courbe du CTR pour les landing pages différentes, il faut le faire.

# The function for creating and saving each directory charts
def each_dir_plot(dir_df, key):
    # Grouping directory landing pages based on their 'position label' value
    dir_grouped_df = dir_df.groupby(['position label'])


    # Creating a DataFrame for storing 'dir_grouped_df' manipulated data
    modified_df = pd.DataFrame()

    # A list for saving each position mean for our bar chart
    mean_ctr_list = []


    '''
    Looping over 'query_grouped_df' groups and appending the top 20% queries based on the impressions to the 'modified_df' DataFrame.
    If calculating CTR only based on the top 20% of queries having the most impressions is not the best for you, you can change it.
    For changing it, you can increase or decrease it by manipulating '.quantile(q=your_optimal_number, interpolation='lower')]'.
    'you_optimal_number' must be between 0 to 1. 
    For example, if you want to get the top 30% of your queries, 'your_optimal_num' is the difference between 1 and ‌0.3 (0.7).
    '''
    for i in range(1, 11):
        # A try-except for handling those situations that a directory hasn't any data for some positions
        try:
            tmp_df = dir_grouped_df.get_group(i)[dir_grouped_df.get_group(i)['impressions'] >= dir_grouped_df.get_group(i)['impressions']
                                                 .quantile(q=0.8, interpolation='lower')]
            mean_ctr_list.append(tmp_df['ctr'].mean())
            modified_df = modified_df.append(tmp_df, ignore_index=True)
        except KeyError:
            mean_ctr_list.append(0)


    # 1. The box plot
    box_fig = px.box(modified_df, x='position label', y='ctr', title=f'{key} directory CTR distribution based on position',
                 points='all', color='position label', labels={'position label': 'Position', 'ctr': 'CTR'})

    # Showing all ten x-axes ticks
    box_fig.update_xaxes(tickvals=[i for i in range(1, 11)])

    # Changing the y-axes tick format to percentage
    box_fig.update_yaxes(tickformat=".0%")

    # Saving plot to 'output plot images' directory
    box_fig.write_image(f'./output plot images/{key} directory-Box plot CTR curve.png')


    # 2. The bar plot
    bar_fig = px.bar(x=[pos for pos in range(1, 11)], y=mean_ctr_list, title=f'{key} directory mean CTR distribution based on position',
                  labels={'x': 'Position', 'y': 'CTR'}, text_auto=True)

    # Showing all ten x-axes ticks
    bar_fig.update_xaxes(tickvals=[i for i in range(1, 11)])

    # Changing the y-axes tick format to percentage
    bar_fig.update_yaxes(tickformat='.0%')

    # Saving plot to 'output plot images' directory
    bar_fig.write_image(f'./output plot images/{key} directory-Bar plot CTR curve.png')

Après avoir défini la fonction ci-dessus, il faut créer une boucle ‘for’ afin de parcourir les données des répertoires pour lesquelles vous souhaitez obtenir la courbe CTR.

# Looping over directories and executing the 'each_dir_plot' function
for key, item in landings_grouped_df:
    if key in important_directories:
        each_dir_plot(item, key)

Dans les résultats, vous obtenez vos diagrammes dans le dossier output plot images .

Courbe CTR Python_output plot images

Astuce avancée !

Vous pouvez également calculer les courbes CTR des différents répertoires en utilisant la landing page des requêtes. Avec quelques changements dans les fonctions, vous pouvez regrouper les requêtes en fonction de leurs répertoires de landing pages.

Vous pouvez utiliser la requête ci-dessous afin d’effectuer une demande d’API dans l’API Explorer (n’oubliez pas la limite de 25 000 lignes) :

{
  "startDate": "2022-01-01",
  "endDate": "2022-02-01",
  "dimensions": [
    "query",
    "page"
  ],
  "dimensionFilterGroups": [
    {
      "filters": [
        {
          "dimension": "QUERY",
          "expression": "brand_variation_names",
          "operator": "EXCLUDING_REGEX"
        }
      ]
    }
  ],
  "rowLimit": 25000
}

Les conseils pour personnaliser le calcul de la courbe CTR avec Python

Afin d’obtenir les données plus précises pour calculer la courbe CTR, vous serez obligé d’utiliser des outils tiers.

En plus de savoir quelles requêtes comportent un featured snippet, vous pouvez explorer plus de fonctionnalités SERP.

En outre, si vous utilisez des outils tiers, vous pouvez obtenir la paire de requêtes avec le positionnement de la landing page pour cette requête ; en fonction des caractéristiques des SERPs.

Ensuite, étiquetez les landing pages avec leur répertoire racine (parent), regroupez les requêtes en fonction des valeurs du répertoire en tenant compte les caractéristiques des SERPs, puis regroupez les requêtes relativement à la position. Pour les données de CTR, vous pouvez fusionner les valeurs de CTR du GSC avec celles des requêtes homologues.

Alireza Esmikhani Voir tous ses articles
Alireza, spécialiste du SEO, travaille dans le domaine du SEO et du SEM depuis quelques années, en collaborant avec les départements marketing, technique et produits. Son objectif est d'aider les entreprises à améliorer leurs performances et à atteindre leurs objectifs. Alireza cherche à acquérir en permanence de nouvelles compétences et à développer son expertise.
Sujets en lien :