Site icon Anakeyn

Importer les données de Google Analytics API avec Python Anaconda

Dans un article précédent, nous avions vu comment importer des données de Google Analytics avec R. Cette fois-ci nous allons voir comment effectuer une opération équivalente avec Anaconda et Python et l’API de Google Analytics V4. Suivez les étapes qui vous concernent ci-dessous.

Installation de Python Anaconda

Anaconda se présente comme une plateforme dédiée aux sciences de données. Dans les faits, Anaconda est construit à partir de Python et inclut de nombreuses bibliothèques spécialisées en data science, comme par exemple scikit-learn, Numpy, Pandas, TensorFlow … Anaconda est compatible Windows, Mac et Linux. Rendez vous sur la page de téléchargement d’Anaconda Distribution pour télécharger la version qui vous concerne. Pour notre part, nous sommes sous Windows.

A l’heure ou je vous écris, la dernière version en Python 3 d’Anaconda est la 3.7. Remarque : tous nos tests sont en Python 3.xx.

Lors de l’installation nous vous conseillons de prendre les options par défaut du Logiciel notamment le répertoire pour Anaconda : C:\Users\MonNom\Anaconda3.

Une fois l’installation terminée, vous verrez apparaitre différentes applications avec Anaconda dans le menu Windows :

Vous trouverez notamment :

Création d’un projet sur la Console Google et codes OAuth.

Afin de pouvoir accéder à l’API de Google Analytics il est nécessaire de créer un projet sur la console développeur de Google : https://console.developers.google.com.

Nous avions déjà décrit la procédure pour créer ce compte et récupérer ses codes sur la page https://www.anakeyn.com/2018/03/01/googleanalyticsr-import-google-analytics-r/ à la rubrique « Projet sur Console Google et codes OAuth ».

Récupérez et sauvegardez votre code client et votre code secret du genre :

Utilisez vos codes, pas les miens, de toute façon ceux-ci sont faux.

Installer la bibliothèque google-api-python-client fournie par Google.

Attention ici, utilisez le gestionnaire de paquet « conda » d’Anaconda plutôt que le gestionnaire de paquets « pip ».

Ouvrez l’invite de commande Anaconda (Anaconda Prompt) et saisissez :

 conda install -c conda-forge google-api-python-client 

Installer la bibliothèque de gestion de l’authentification  oauth2client

Comme précédemment, utilisez conda, ouvrez l’invite de commande Anaconda (Anaconda Prompt) et saisissez :

 conda install -c conda-forge oauth2client 

Code Source

N’hésitez pas à copier/coller les codes sources suivants. Comme nous vous l’indiquions précédemment nous faisons tourner le programme dans l’environnement de développement Spyder.

Vous pouvez aussi récupérer gratuitement le code source en entier sur notre boutique à l’adresse : https://www.anakeyn.com/boutique/produit/script-python-import-de-donnees-google-analytics/

Chargement des bibliothèques utiles

Dans cette partie nous chargeons les bibliothèques générales dont nous avons besoin. On s’assure aussi que l’on est dans le bon répertoire. Ceci peut aussi se faire en vérifiant le répertoire courant dans Spyder en haut à droite).

Vérification du répertoire courant

# -*- coding: utf-8 -*- 
""" 
Created on Thu Jan 17 10:50:38 2019 
@author: Pierre 
""" 
############################################################# 
# Chargement des bibliothèques utiles et positionnement dans 
# le bon répertoire 
############################################################# 
#def main(): #on ne va pas utiliser le main car on reste dans Spyder 
import matplotlib.pyplot as plt #pour les graphiques 
from pandas.plotting import register_matplotlib_converters #pour les dates dans les graphiques 
register_matplotlib_converters() 
import pandas as pd #pour les Dataframes ou tableaux de données 
import seaborn as sns #graphiques étendues 
#pour le chemin courant 
import os #bibliothèque os
print(os.getcwd()) #verif 
#forcer mon répertoire sur ma machine - nécessaire quand on fait tourner le programme 
#par morceaux dans Spyder et que l'on n'a pas indiqué le répertoire en haut à droite. 
#myPath = "C:/Users/MyUSERNAME/myPATH"
#os.chdir(myPath) 
#modification du path 
#print(os.getcwd()) #verif

Connexion aux APIs de Google Via OAuth2

La première fois que vous vous connectez, un navigateur s’ouvre pour autoriser l’accès à l’application que vous aviez créée précédemment dans la console Google API : Connectez vous avec votre compte Google avec lequel vous avez accès à vos données Google Analytics. Pour les fois suivantes un petits fichier est créé dans le répertoire courant et qui comporte vos codes d’autorisations de connexions à l’appli. Remarque : ce code source s’inspire de celui proposé par Google : https://developers.google.com/analytics/devguides/reporting/core/v4/quickstart/installed-py

#
#
###############################################################################
#Code inspiré de  Hello Analytics API fourni par Google qui va nous aider 
#pour se connecter à l'API De Google Analytics 
# infos sur le sujet 
#https://developers.google.com/analytics/devguides/reporting/core/v4/quickstart/installed-py


import argparse #module d’analyse de ligne de commande

#pour se connecter
from apiclient.discovery import build
import httplib2
from oauth2client import client
from oauth2client import file
from oauth2client import tools
#from oauth2client.service_account import ServiceAccountCredentials  

#Les Mauvais clients (pas la peine de les copier - prenez les votres)
MYCLIENTID = "XXXXXXXXX-qb0pgbntdmvf32i1kni67u2o455t0rbh.apps.googleusercontent.com" 
MYCLIENTSECRET =    "Mi_JcEQRuBgOLHDj8MH_s0uw" 

SCOPE  = ['https://www.googleapis.com/auth/analytics.readonly']

# Analyse des arguments de ligne de commande
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, 
                                 parents=[tools.argparser])
flags = parser.parse_args([])

# Créer un objet flow pour connection oAuth
flow = client.OAuth2WebServerFlow(client_id=MYCLIENTID,
                           client_secret=MYCLIENTSECRET,
                           scope='https://www.googleapis.com/auth/analytics.readonly')
  


# Prepare credentials, and authorize HTTP object with them.
# If the credentials don't exist or are invalid run through the native client
# flow. The Storage object will ensure that if successful the good
# credentials will get written back to a file.
storage = file.Storage('analyticsreporting.dat')
credentials = storage.get()
if credentials is None or credentials.invalid:
  credentials = tools.run_flow(flow, storage, flags)
http = credentials.authorize(http=httplib2.Http())

Récupération de l’ID de vue de Google Analytics

On récupère l’id de vue en faisant appel à Google Analytics V3 (je n’ai pas trouver de méthode avec la version 4). Sinon aller la récupérer « à la main » dans Google Analytics.

#Analytics V3 pour la liste des comptes et récupréation des View_ID
analyticsV3 = build('analytics', 'v3', http=http)
accounts = analyticsV3.management().accounts().list().execute()
total_accounts = accounts.get('totalResults')
for i in range(0,total_accounts) :
    account = accounts.get('items')[i].get('id')
    properties = analyticsV3.management().webproperties().list(
        accountId=account).execute()
    total_properties = properties.get('totalResults')
    for j in range(0,total_properties) : 
        property = properties.get('items')[j].get('id')
        profiles = analyticsV3.management().profiles().list(accountId=account,webPropertyId=property).execute() 
        total_profiles = profiles.get('totalResults')
        for k in range(0,total_profiles) :
            print("Site:"+profiles.get('items')[k].get('websiteUrl')+" Vue:"+profiles.get('items')[k].get('name')+" ID de Vue:"+profiles.get('items')[k].get('id'))
              
#on prend l'ID De vue vue qui nous intéresse pour nous le premier 
VIEW_ID = '47922230' 

Transformation de la réponse de l’API Google Analytics en DataFrame.

Comme on aime bien avoir nos jeux de données sous la forme de DataFrame comme dans R, on va transformer la réponse de Google Analytics API. pour cela on récupère une fonction de nos confrères de « The Marketing Technologist » : https://www.themarketingtechnologist.co/getting-started-with-the-google-analytics-reporting-api-in-python/

#######################################################################    
#Transformation de la réponse Google Analytics au format dataframe
#voir ici : 
#https://www.themarketingtechnologist.co/getting-started-with-the-google-analytics-reporting-api-in-python/
          
def dataframe_response(response):
  list = []
  # get report data
  for report in response.get('reports', []):
    # set column headers
    columnHeader = report.get('columnHeader', {})
    dimensionHeaders = columnHeader.get('dimensions', [])
    metricHeaders = columnHeader.get('metricHeader', {}).get('metricHeaderEntries', [])
    rows = report.get('data', {}).get('rows', [])
    
    for row in rows:
        # create dict for each row
        dict = {}
        dimensions = row.get('dimensions', [])
        dateRangeValues = row.get('metrics', [])

        # fill dict with dimension header (key) and dimension value (value)
        for header, dimension in zip(dimensionHeaders, dimensions):
          dict[header] = dimension

        # fill dict with metric header (key) and metric value (value)
        for i, values in enumerate(dateRangeValues):
          for metric, value in zip(metricHeaders, values.get('values')):
            #set int as int, float a float
            if ',' in value or '.' in value:
              dict[metric.get('name')] = float(value)
            else:
              dict[metric.get('name')] = int(value)

        list.append(dict)
    
    df = pd.DataFrame(list)
    return df
######################################################################


Récupération des données :

On va ici récupérer les données de Google Analytics pour le site d’une association, Networking Morbihan dont nous avons déjà parlé dans un article sur le nettoyage du spam via les segments de Google Analytics. L’avantage de ce jeu de données est que nous avons 7 ans 1/2 d’historique, ce qui pourra nous servir pour d’autres articles. Si vous souhaitez personnaliser votre requête et savoir quelles métriques et quelles dimensions vous pouvez utiliser, reportez vous au Guide de Google Analytics V4 : https://developers.google.com/analytics/devguides/reporting/core/dimsmets

#########################################################################
# RECUPERATION DES DONNEES
##########################################################################
#Pages Vues sur toutes les années précédentes Trafic Brut 
def get_gaAllYears(analyticsV4, VIEW_ID):
  # Use the Analytics Service Object to query the Analytics Reporting API V4.
  return analyticsV4.reports().batchGet(
      body={
        'reportRequests': [
        {
          'viewId': VIEW_ID,
          'pageSize': 10000,  #pour dépasser la limite de 1000
          'dateRanges': [{'startDate': "2011-07-01", 'endDate': "2018-12-31"}],
          'metrics': [{'expression': 'ga:pageviews'}],
          'dimensions': [{'name': 'ga:date'}],
        }]
      }
  ).execute()

    
# Build the service object. en version V4 de Google Analytics API
analyticsV4 = build('analyticsreporting', 'v4', http=http)

response = get_gaAllYears(analyticsV4, VIEW_ID)  #récupération des données de Google Analytics

#Données récupérées de GA
gaAllYears = dataframe_response(response) #on récupère la réponse brute en dataframe.
#creation de la variable Année à partir de ga:date
gaAllYears['Année'] = gaAllYears['ga:date'].astype(str).str[:4]
#changement des noms de colonnes ga:date et ga:pageviews car le ":" gêne
#pour manipuler les colonnes.
gaAllYears = gaAllYears.rename(columns={'ga:date': 'date', 'ga:pageviews': 'pageviews'})
#transformation date string en datetime 
gaAllYears.date = pd.to_datetime(gaAllYears.date,  format="%Y%m%d")
#verifs
gaAllYears.dtypes
gaAllYears.count()  #2668 enregistrements 
gaAllYears.head(20)

Graphique du trafic sur plusieurs années :

Pour que cela soit plus visible on va utiliser différentes couleurs selon les années :

##########################################################################
#Graphique avec des années de différentes couleurs.
sns.set()  #paramètres esthétiques ressemble à ggplot par défaut.
fig, ax = plt.subplots()  #un seul plot
sns.lineplot(x='date', y='pageviews', hue='Année', data= gaAllYears, 
                  palette=sns.color_palette("husl",n_colors=8))
fig.suptitle('Il semble y avoir une anomalie en fin 2016.', fontsize=14, fontweight='bold')
ax.set(xlabel='Année', ylabel='Nombre de pages vues par jour',
       title='le trafic est bien au dessus du reste des observations.')
fig.text(.3,-.03,"Nombre de pages vues par jour depuis 2011 - Données brutes", 
         fontsize=9)
plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
#plt.show()
fig.savefig("PV-s2011.png", bbox_inches="tight", dpi=600)

Pages Vues en Moyenne mobile sur 30 jours

Pour clarifier le graphique, essayons d’afficher celui-ci en moyenne mobile sur 30 jours.

##################################################################
# moyenne mobile
##########################################################################
#Graphique Moyenne Mobile 30 jours.
#calcul de la moyenne mobile sur 30 jours
gaAllYears['cnt_ma30'] =  gaAllYears['pageviews'].rolling(window=30).mean()

sns.set()  #paramètres esthétiques ressemble à ggplot par défaut.
fig, ax = plt.subplots()  #un seul plot
sns.lineplot(x='date', y='cnt_ma30', hue='Année', data= gaAllYears, 
                  palette=sns.color_palette("husl",n_colors=8))
fig.suptitle("L'anomalie fin 2016 est bien visible.", fontsize=14, fontweight='bold')
ax.set(xlabel='Année', ylabel='Nbre pages vues / jour en moyenne mobile',
       title='le trafic est bien en dessous du reste des observations.')
fig.text(.9,-.05,"Nombre de pages vues par jour depuis 2011 en moyenne mobile sur 30 jours \n Données brutes", 
         fontsize=9, ha="right")
plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
#plt.show()
fig.savefig("PV-s2011-Moyenne-Mobile.png", bbox_inches="tight", dpi=600)

J’espère que cette première présentation sur l’API de Google Analytics avec Python vous aura été utile.

N’hésitez pas à faire vos remarques et suggestions et poser vos questions en commentaires.

Dans plusieurs prochains articles nous tirerons au clair cette affaire d’anomalie en 2016 🙂

A Bientôt,

Pierre

Quitter la version mobile