Google Analytics è un servizio di analisi di dati che consente di ottenere informazioni dettagliate sul traffico del proprio sito web e sull'efficacia delle campagne di marketing Google AdSense e Google AdWords.
In questo articolo vedremo come usare le API di Google Analytics per realizzare applicazioni client (o Web) che interrogano i dati raccolti ed elaborati da Google Analytics.
Per iniziare vediamo come attivare un account e monitorare un sito Web. Chi possiede già un account e un profilo su Google Analytics, può leggere direttamente la parte successiva sulla Google Analytics Data Export API
Account su Google Analytics
Per poter usare Google Analytics bisogna creare (gratuitamente) un Account Analytics. Dopo la creazione dell'account vedremo come creare dei profili e associarli ai siti web che vogliamo monitorare. Vedremo che, per consentire ad Analytics di registrare le informazioni, è sufficiente inserire un codice JavaScript nelle pagine web da monitorare.
Creare l'account Google è molto semplice, come si vede nella Guida Google Analytics, dopo averlo creato, possiamo accedere all'interfaccia amministrativa fornendo le nostre credenziali.
Infine potremo controllare il traffico dei siti e analizzare i dati tramite i report proposti dall'interfaccia stessa o graziie a report personalizzati.
Creare un profilo
La prima cosa da fare per monitorare un sito (o una pagina) è associarlo un profilo di Analytics. Un utente può avere uno o più profili.
In figura vediamo che l'utente simonmor@tiscali.it
, possessore dell'account simonemoretti75
, ha un solo profilo relativo al sito www.mariomoretti.it
. Se clicchiamo sul link "Visualizza rapporto" ci viene proposto il report (Figura 1) che evidenzia l'andamento delle visite del sito nell'ultimo mese. Nel menu di sinistra troviamo altri report che riportano dati relativi ai visitatori, ai referer del sito e molto altro ancora.
Includere il codice JavaScript nelle pagine Web
Il codice Javascript da inserire nelle pagine web ci viene fornito dall'amministrazione nel momento in cui creiamo un nuovo profilo. Se clicchiamo su Aggiungi nuovo profilo
, appare una nuova pagina in cui inserire l'indirizzo del nuovo sito da monitorare. Fatto questo, accediamo ad una pagina che riepiloga le caratteristiche del nuovo profilo e fornisce il codice JavaScript da inserire nelle pagine web del nostro sito subito prima del tag di chiusura </head>
(figura 5).
Ulteriori approfondimenti su Google Analytics si possono trovare sulla guida.
Le Google Data API
Le Google Data API (abbreviate in GData API) costituiscono un framework molto versatile che ci consente di accedere e gestire i dati messi a disposizione dai vari servizi Google.
Queste librerie hanno in comune un protocollo di comunicazione chiamato Google Data Protocol, basato su standard come HTTP, REST, AtomPub, JSON, che possiamo sfruttare per interfacciare un client o una applicazione Web ai servizi remoti.
A questo scopo sono dispobili anche alcune librerie client per diverse piattaforme (Java, JavaScript, .NET, PHP, Python). Queste librerie introducono un livello di astrazione che ci consente di non dover lavorare a basso livello sul protocollo HTTP ma di interagire con oggetti che rappresentano i dati trasmessi (feed, entry, account utente, profili, etc.).
In questo articolo utilizzeremo solo le Google Analytics Data Export API che servono ad interfacciarsi con i dati web monitorati da Google Analytics, i più curiosi e intraprendenti possono consultare l'elenco completo delle API.
Google Analytics Data Export API
Con le Google Analytics Data Export API (in breve GA Export API) si possono implementare applicazioni client (o Web) per richiedere dati da un profilo di un utente possessore di un account Analytics. Attualmente questa API ci permette di accedere ai dati in sola lettura.
I dati Analytics si possono raggruppare in due categorie principali:
- dati dell'utente: account e profilo
- dati del sito web: reportistica sul traffico del sito
Per poter prelevare e maneggiare i nostri dati di Google Analytics è necessario eseguire una sequenza di quattro passi:
1. Autenticazione
Fase in cui noi, o gli utenti della nostra applicazione, ci facciamo riconoscere da Google con le credenziali di accesso. Esistono tre meccanismi di autenticazione: ClientLogin, AuthSub e OAuth. Li esamineremo in dettaglio in seguito.
2. Autorizzazione
Ogni account può avere più profili Analytics, generalmente un profilo per ogni sito monitorato. Dopo aver autenticato l'utente dobbiamo, quindi, determinare quali sono i profili sui quali operare. I profili hanno un identificativo numerico che li individua univocamente. Se già conosciamo l'id questo passo risulta superfluo, altrimenti dobbiamo consentire all'utente di scegliere uno dei propri profili.
3. Eseguire la query sul profilo
Una volta autenticato l'utente ed individuato l'identificativo del profilo di nostro interesse possiamo interrogare il sistema.
4. Decodificare il risultato della query
Google ci restituirà il risultato della query in una risposta HTTP sotto forma di data feed. Per default il formato usato da Google è Atom ma possiamo impostare anche altri formati standard come RSS o JSON.
Possiamo decodificare il risultato sia a basso livello, maneggiando direttamente la risposta HTTP, sia ad alto livello usando le librerie client fornite da Google (per .NET usiamo GData .NET Client Library). Negli esempi che faremo percorreremo entrambe le strade.
GData .NET Client Library
La GData .NET Client Library è una libreria .NET rilasciata dal Google Data team, grazia alla quale interagire ad alto livello con i servizi remoti GData. Possiamo scaricare l'ultima versione della libreria dalla home page del sito.
Procediamo con l'installazione della libreria lanciando il file Google Data API Setup(1.6.x.x).msi
che abbiamo scaricato. L'installazione copia in una cartella le DLL associate alle GData API supportate.
Una volta installate le DLL possiamo cominciare a sfruttarle nelle nostre applicazioni (anche Client). Tutto ciò che dobbiamo fare è referenziare nelle applicazioni web le dll che ci servono. Nei nostri esempi avremo bisogno di tre dll:
Libreria | Descrizione |
---|---|
Google.GData.Client | dll con gli oggetti e le funzionalità di base della GData API |
Google.GData.Extensions | dll con gli oggetti e le funzionalità specifiche della GA Export API |
Google.GData.Analytics | dll con estensioni alle funzionalità base della GData API |
dovremo poi includere nei sorgenti i relativi namespace:
using Google.GData.Client;
using Google.GData.Extensions;
using Google.GData.Analytics;
Autenticazione ClientLogin
Quando un utente richiede dei dati ad Analytics, deve essere riconosciuto da Google attraverso le credenziali di accesso: la coppia email-password dell'account Google. Le Google Analytics Data Export API supportano tre meccanismi di autenticazione, ClientLogin, AuthSub e OAuth, che andiamo a vedere nel dettaglio.
Il metodo ClientLogin è il più semplice dei tre ma anche il meno sicuro. Consiste nel chiedere le credenziali di accesso da una maschera della applicazione client. Visto che con questo metodo è l'applicazione a maneggiare le credenziali di accesso è consigliabile usarlo solo se l'applicazione è di tipo desktop (non web) ed è usata dal proprietario del PC sulla quale risiede.
È assolutamente da evitare se l'applicazione è web e maneggia le credenziali di accesso di terze parti perché non sarebbe garantita la sicurezza dei dati degli utenti.
Se il servizio di autenticazione di Google non riconosce le credenziali di accesso risponde con un codice di errore HTTP 401
che indica l'insuccesso dell'autenticazione, se invece le credenziali sono valide ci viene restituito il codice HTTP 200
ed un token con il quale effettuare tutte le richieste HTTP successive. Sarà questo token a garantire che l'utente è già autenticato.
Vediamo, con un esempio, come effettuare il passaggio delle credenziali di accesso attraverso una richiesta HTTP e come decodificare il token restituito nella risposta HTTP del servizio di autenticazione:
// le credenziali di accesso inserite dall'utente
string postData = "Email=" + TxtEmail.Text + "&Passwd=" + TxtPassword.Text;
//altri parametri necessari, in source mettiamo il nome della applicazione
postData = postData + "&accountType=GOOGLE" + "&service=analytics" + "&source=SimoneMoretti-gdataSamples-1";
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] data = encoding.GetBytes(postData);
// creiamo una richiesta http di tipo POST
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create("https://www.google.com/accounts/ClientLogin");
myRequest.Method = "POST";
myRequest.ContentType = "application/x-www-form-urlencoded";
myRequest.ContentLength = data.Length;
Stream newStream = myRequest.GetRequestStream();
// spediamo la richiesta HTTP
newStream.Write(data, 0, data.Length);
newStream.Close();
// Intercettiamo la risposta
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
Stream responseBody = myResponse.GetResponseStream();
Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
StreamReader readStream = new StreamReader(responseBody, encode);
// Risposta in formato stringa
string response = readStream.ReadToEnd();
//preleviamo il token di autorizzazione
string[] auth = response.Split(new string[] { "Auth=" }, StringSplitOptions.None);
//mettiamo il token in sessione in modo da usarlo nelle richieste successive
Session["token"] = auth[1];
Per creare una richiesta HTTP utilizziamo la classe HttpWebRequest
contenuta nel namespace System.Net
. Le credenziali di accesso vanno spedite al servizio di autenticazione di Google che risponde alla URL:
https://www.google.com/accounts/ClientLogin
Oltre ad email e password vanno forniti altri parametri che riepiloghiamo nella seguente tabella:
Parametro | Descrizione |
---|---|
accountType |
Il tipo di account per il quale richiedere l'autorizzazione. Al momento l'unico valore supportato da Google analytics è GOOGLE |
Email |
L'indirizzo email dell'account Google dell'utente funge da username |
Passwd |
La password dell'account Google |
service |
Il nome del servizio Google da richiedere, nel nostro caso è analytics |
source |
Una stringa che identifica la nostra applicazione client nella forma companyName-applicationName-versionID |
La richiesta HTTP deve essere di tipo POST
perché stiamo chiedendo al servizio la creazione di un token di autenticazione.
Per intercettare la risposta HTTP usiamo la classe HttpWebResponse
contenuta nel NameSpace System.Net
. Della risposta ci interessa il token di autenticazione il cui valore si trova dopo il parametro Auth
.
Autenticazione attraverso la .NET Client Library
Vediamo ora come l'autenticazione risulta più semplice usando la GData .NET Client Library. Esaminiamo questo brano di codice:
// Configuriamo il servizio Google di autenticazione con il nome della app
asv = new AnalyticsService("SimoneMoretti-gdataSamples-1");
// Passiamo le credenziali di accesso al servizio.
asv.setUserCredentials(TxtEmail.Text, TxtPassword.Text);
Anzitutto configuriamo il servizio di autenticazione creando un'istanza della classe AnalyticsService
del NameSpace Google.GData.Analytics
. A differenza del metodo precedente dobbiamo indicare il solo nome della applicazione client che effettua la richiesta di autenticazione.
Lanciamo poi il metodo setUserCredentials
, al quale passiamo i soli parametri di accesso. Siamo riusciti a fare in due sole righe di codice quello che con il metodo precedente abbiamo ottenuto con 18 righe e, cosa ancor più interessante, è la libreria ad occuparsi della gestione del token di autenticazione, in modo a noi del tutto invisibile. Più avanti approfondiremo meglio l'uso della GData .NET Client Library.
Autenticazione AuthSub
Questo metodo è particolarmente adatto ad applicazioni Web e alle applicazioni desktop che gestiscono account Google di terzi. In questo caso non è l'applicazione a gestire le credenziali di accesso, queste infatti vengono inserite su una pagina Web ospitata su un server Google, ciò a garanzia di maggior sicurezza.
Il procedimento di autenticazione è leggermente diverso dal metodo ClientLogin: quando l'utente effettua la richiesta di autenticazione gli viene restituito un token monouso che deve consumare in una seconda richiesta di autenticazione che restituisce un token multi-sessione. Quest'ultimo può essere utilizzato dall'utente per tutte le richieste successive.
Quindi rispetto al metodo ClientLogin le credenziali di accesso vengono fornite in un web form remoto e il token multisessione viene fornito solo alla seconda richiesta. Mettiamo in pratica il metodo passo dopo passo:
1. La prima richiesta
Esaminiamo la composizione dell'URL che utilizziamo per la prima richiesta, per farlo la scriviamo "spezzettata":
https://www.google.com/accounts/AuthSubRequest? &next=http://localhost:1627/tradizionale.aspx &scope=https://www.google.com/analytics/feeds/ &secure=0 &session=1
Questa URL sarà accessibile per mezzo di un link o di un pulsante, contiene i seguenti parametri:
Parametro | Descrizione |
---|---|
next |
URL dove l'utente verrà redirezionato dopo aver fornito le credenziali di accesso. È la pagina della applicazione client che si occupa di richiedere il token multisessione |
scope |
Indica che l'applicazione sta richiedendo il token multisessione per accedere a dati Analytics. Questo campo deve essere: https://www.google.com/analytics/feeds/ |
secure |
Valore booleano che indica se la transazione di autorizzazione deve rilasciare o meno un token sicuro. I token sicuri sono disponibili solo per le applicazioni registrate |
session |
Valore booleano che impostato a uno indica che il token rilasciato deve essere usato per una seguente richiesta di token multisessione |
Quando forniamo le credenziali di accesso il sistema ci redireziona verso la URL specificata nel parametro next
ed appende un token monouso come parametro. Nella pagina di approdo dobbiamo intercettare il token monouso e fornirlo come parametro a questa URL:
https://www.google.com/accounts/AuthSubSessionToken
che ritorna il token multisessione. Vediamo un esempio:
string token = Request.QueryString["token"]; //token mono-uso
//effettuiamo una richiesta HTTP per il token multi-sessione
HttpWebRequest myRequest = (HttpWebRequest) WebRequest.Create("https://www.google.com/accounts/AuthSubSessionToken");
myRequest.Headers.Add("Authorization: AuthSub token=" + token);
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
Stream responseBody = myResponse.GetResponseStream();
Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
StreamReader readStream = new StreamReader(responseBody, encode);
//trasformiamo la risposta HTTP in stringa
string response = readStream.ReadToEnd();
//mettiamo in sessione il token multiuso
Session["token"] = response.Split('=')[1];
Utilizziamo una richiesta HTTP di tipo GET inserendo nella sezione Header
il token monouso ottenuto al passo precedente. A questo punto riceviamo il token "multiuso" dalla risposta e lo immagaziniamo nel nostro oggetto Session
.
È possibile usare il metodo AuthSub anche con le librerie client.
Autenticazione OAuth
OAuth è un metodo adatto sia per applicazioni desktop che web. Come AuthSub fornisce un token di autenticazione e esonera le applicazioni dal maneggiare le credenziali di accesso dell'utente. A differenza di AuthSub però è necessario registrare le applicazioni con un certificato di sicurezza. Non approfondiamo oltre questo metodo che però troviamo documentato in questo articolo.
Eseguire le query
Una volta passata l'autenticazione possiamo procedere alla richiesta dei dati. Dobbiamo solo ricordare di inserire il nostro token di autenticazione nella sezine header di tutte le richieste HTTP.
Come abbiamo detto in precedenza possiamo scegliere se richiedere i dati utente o i report sul traffico, per iniziare vediamo come ottenere le informazioni su account e profili.
Richiedere dati dell'utente
Per richiedere i dati relativi ad un account utente è necessario fare una richiesta HTTP di tipo GET alla URL:
https://www.google.com/analytics/feeds/accounts/default
Per mezzo del token multisessione il servizio remoto di Google che risponde a quest'indirizzo identifica l'utente che ha effettuato la richiesta e risponde restituendo un Account Feed in formato XML. Esaminiamolo:
Account Feed | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Tag | Descrizione | ||||||||||||||||
id |
è una URI univoca dalla forma: https://www.google.com/analytics/feeds/ accounts/simonmor@tiscali.it |
||||||||||||||||
title |
È la stringa "Account list for" seguita dal nome dell'utente autenticato | ||||||||||||||||
totalResults |
il numero totale di risultati per la query | ||||||||||||||||
startIndex |
l'indice di partenza per le entry, di default è uno | ||||||||||||||||
itemsPerPage |
il numero di elementi nella richiesta corrente, il valore massimo è mille | ||||||||||||||||
entry |
Ci possono essere uno o più oggetti entry formati dalle seguenti proprietà
|
Ecco un Account Feed di esempio:
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:dxp="http://schemas.google.com/analytics/2009" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/">
<id>http://www.google.com/analytics/feeds/accounts/abc@prova.it</id>
<updated>2010-06-29T02:05:01.413-07:00</updated>
<title type="text">Profile list for abc@prova.it </title>
<link rel="self" type="application/atom+xml"
href="https://www.google.com/analytics/feeds/accounts/default" />
<author>
<name>Google Analytics</name>
</author>
<generator version="1.0">Google Analytics</generator>
<openSearch:totalResults>2</openSearch:totalResults>
<openSearch:startIndex>1</openSearch:startIndex>
<openSearch:itemsPerPage>2</openSearch:itemsPerPage>
<entry>
<id>http://www.google.com/analytics/feeds/accounts/ga:174288</id>
<updated>2010-06-29T02:05:01.413-07:00</updated>
<title type="text">www.mariomoretti.it</title>
<link rel="alternate" type="text/html"
href="http://www.google.com/analytics" />
<dxp:property name="ga:accountId" value="86539" />
<dxp:property name="ga:accountName" value="mariomoretti" />
<dxp:property name="ga:profileId" value="174288" />
<dxp:property name="ga:webPropertyId" value="UA-86539-1" />
<dxp:property name="ga:currency" value="USD" />
<dxp:property name="ga:timezone" value="Europe/Rome" />
<dxp:tableId>ga:174288</dxp:tableId>
</entry>
<entry>
<id>http://www.google.com/analytics/feeds/accounts/ga:331664</id>
<updated>2010-05-28T17:28:02.857-07:00</updated>
<title type="text">www.simonemoretti75.wordpress.com</title>
<link rel="alternate" type="text/html"
href="http://www.google.com/analytics" />
<dxp:property name="ga:accountId" value="86539" />
<dxp:property name="ga:accountName" value="mariomoretti" />
<dxp:property name="ga:profileId" value="331664" />
<dxp:property name="ga:webPropertyId" value="UA-86539-3" />
<dxp:property name="ga:currency" value="USD" />
<dxp:property name="ga:timezone" value="America/Los_Angeles" />
<dxp:tableId>ga:331664</dxp:tableId>
</entry>
</feed>
In questo Account Feed possiamo trovare tutti gli elementi principali citati nella tabella precedente. La prima indicazione che troviamo è che si tratta di un file XML e la che il feed restituito è in formato Atom. Troviamo poi il valore della proprietà id
e via via tutti gli altri elementi proposti in tabella.
Possiamo facilmente verificare che nell'account feed restituito, abbiamo un account utente avente identificativo 86539
e nome mariomoretti
con due profili aventi identificativi 174288
e 331664
. Il primo profilo fa riferimento al sito www.mariomoretti.it
, il secondo profilo invece fa riferimento al sito www.simonemoretti75.wordpress.com
. Notiamo come il primo sito sia impostato sulla zona temporale di Roma e come il secondo sulla zona temporale di Los Angeles.
Esaminiamo un esempio di codice che richiede i dati di un account:
//creiamo una richiesta http di tipo GET
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create("https://www.google.com/analytics/feeds/accounts/default");
//mettiamo il token multisessione nell'header della richiesta
myRequest.Headers.Add("Authorization: GoogleLogin auth=" + token);
//inviamo la richiesta e intercettiamo la risposta
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
Ricordiamoci che prima di effettuare la richiesta dell'account dobbiamo autenticarci come abbiamo già visto. Nella variabile token
è contenuto il token multisessione che dobbiamo aggiungere nell'header della richiesta HTTP al fine di essere autenticati. La richiesta HTTP è identificata dall'oggetto myRequest
di tipo HttpWebRequest
. Per ricevere la risposta dal servizio remoto dobbiamo invocare il metodo GetResponse()
dell'oggetto myRequest
. Vedremo più avanti come decodificare il risultato della query.
Vediamo ora come si ottiene la stessa cosa con la GData .NET Client Library:
// Configuriamo il servizio Google di autenticazione con il nome della app
asv = new AnalyticsService("SimoneMoretti-gdataSamples-1");
// Passiamo le credenziali di accesso al servizio.
asv.setUserCredentials(TxtEmail.Text, TxtPassword.Text);
// Creiamo una query di tipo Account.
AccountQuery query = new AccountQuery();
// eseguiamo la query e mettiamo il risultato in un oggetto di tipo AccountFeed
AccountFeed accountFeed = asv.Query(query);
Confrontando i due approccim notiamo che usando la libreria lavoriamo con astrazioni di alto livello: si maneggiano richieste HTTP ma si lavora con oggetti tipici del mondo Google Analytics. Occorre solo creare un oggetto di tipo AccountQuery
e passarlo al servizio di tipo AnalyticsService
, al quale abbiamo precedentemente passato le credenziali di accesso. Questo rende del tutto invisibile l'esistenza di un token multisessione che viene maneggiato dietro le quinte dalla libreria.
Richiedere i dati di traffico del sito web
Per richiedere i dati relativi al traffico di un sito web è necessario fare una richiesta HTTP di tipo GET alla url:
https://www.google.com/analytics/feeds/data
A questa URL vanno aggiunti dei parametri che servono a costruire la query. Riportiamo nella seguente tabella i principali parametri di ingresso:
Campo | Descrizione |
---|---|
ids |
Identifica il profilo utente |
dimensions |
Uno o più parametri per la segmentazione della metrica (es: visite segmentate per browser dell'utente) |
metrics |
Le statistiche aggregate sulle attività dell'utente (clic, visite, pagine viste, ecc. ) |
sort |
Per l'ordinamento dei risultati |
start-date |
Data di inizio della query |
end-date |
Data di fine della query |
max-results |
Numero massimo di risultati restituiti |
prettyprint |
Se impostato a true indica al servizio remoto di restituire la risposta XML in un formato leggibile per l'uomo |
Mostriamo come richiedere le prime tre pagine più viste del sito associato al profilo 174288
nel mese di Marzo 2010:
https://www.google.com/analytics/feeds/data? ids=ga:174288 &dimensions=ga:pageTitle& metrics=ga:pageviews &sort=-ga:pageviews &start-date=2010-03-01 &end-date=2010-03-31 &prettyprint=true &max-results=3
Per mezzo del token multisessione che agganciamo all'header della richiesta HTTP, il servizio remoto di Google che risponde a quest'indirizzo identifica l'utente che ha effettuato la richiesta e risponde restituendo un Data Feed in formato XML. Vediamo gli elementi principali da cui è composto un Data Feed:
Data Feed | |||||||||
---|---|---|---|---|---|---|---|---|---|
Tag | Descrizione | ||||||||
title |
la stringa "Google Analytics Data for Profile" seguita dall' ID del profilo | ||||||||
id |
la URL del data feed | ||||||||
totalResults |
il numero totale di risultati per la query | ||||||||
startIndex |
l'indice iniziale degli elementi entry, per default è 1 | ||||||||
itemsPerPage |
il numero di elementi nella richiesta corrente, il massimo è 10000 | ||||||||
startDate |
data iniziale della query | ||||||||
endDate |
data finale della query | ||||||||
dataSource |
informazioni sulla sorgente del dato | ||||||||
entry |
ci possono essere uno o più oggetti entry formati dalle seguenti proprietà:
|
Per una migliore comprensione esaminiamo un estratto di un Data Feed relativo alla richiesta precedente:
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"
xmlns:dxp="http://schemas.google.com/analytics/2009"
xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/">
<id>http://www.google.com/analytics/feeds/data?ids=ga:174288&
dimensions=ga:pageTitle&metrics=ga:pageviews&
start-date=2010-03-01&end-date=2010-03-31
</id>
<updated>2010-03-31T16:59:59.999-07:00</updated>
<title type="text">Google Analytics Data for Profile 174288</title>
<author>
<name>Google Analytics</name>
</author>
<generator version="1.0">Google Analytics</generator>
<openSearch:totalResults>10</openSearch:totalResults>
<openSearch:startIndex>1</openSearch:startIndex>
<openSearch:itemsPerPage>5</openSearch:itemsPerPage>
<dxp:dataSource>
<dxp:property name="ga:profileId" value="174288" />
<dxp:property name="ga:webPropertyId" value="UA-86539-1" />
<dxp:property name="ga:accountName" value="www.mariomoretti.it" />
<dxp:tableId>ga:174288</dxp:tableId>
<dxp:tableName>www.mariomoretti.it</dxp:tableName>
</dxp:dataSource>
<dxp:endDate>2010-03-31</dxp:endDate>
<dxp:startDate>2010-03-01</dxp:startDate>
<entry>
<id>http://www.google.com/analytics/feeds/data?ids=ga:174288&
ga:pageTitle=Il%20podismo%20a%20cura%20di%20Mario%20Moretti&
start-date=2010-03-01&end-date=2010-03-31
</id>
<updated>2010-03-30T17:00:00.001-07:00</updated>
<title type="text">ga:pageTitle=Il podismo a cura di Mario Moretti</title>
<link rel="alternate" type="text/html"
href="http://www.google.com/analytics" />
<dxp:dimension name="ga:pageTitle"
value="Il podismo a cura di Mario Moretti" />
<dxp:metric confidenceInterval="0.0" name="ga:pageviews"
type="integer" value="30512" />
</entry>
<entry>
<id>http://www.google.com/analytics/feeds/data?ids=ga:174288&
ga:pageTitle=Calendario%20gare%20podistiche&
start-date=2010-03-01&end-date=2010-03-31
</id>
<updated>2010-03-30T17:00:00.001-07:00</updated>
<title type="text">ga:pageTitle=Calendario gare podistiche</title>
<link rel="alternate" type="text/html"
href="http://www.google.com/analytics" />
<dxp:dimension name="ga:pageTitle" value="Calendario gare podistiche" />
<dxp:metric confidenceInterval="0.0" name="ga:pageviews"
type="integer" value="7080" />
</entry>
</feed>
Il data feed proposto riporta la lista delle pagine più visitate del sito www.mariomoretti.it
nel mese di Marzo 2010. Ogni oggetto entry fornisce il titolo della pagina nel campo dimension ed il numero di visite alla pagina nel campo metric.
Esaminiamo ora un esempio di codice che richiede le 3 pagine più viste di un sito web nel mese di Marzo:
//creiamo una richiesta http di tipo GET
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(
"https://www.google.com/analytics/feeds/data?ids=ga:" +
profileID + "&dimensions=ga:pageTitle&metrics=ga:pageviews&sort=-
ga:pageviews&start-date=2010-03-01&end-date=2010-03-31
&prettyprint=true&max-results=3");
//mettiamo il token multisessione nell'header della richiesta
myRequest.Headers.Add("Authorization: GoogleLogin auth=" + token);
//inviamo la richiesta e intercettiamo la risposta
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
La prassi è la stessa seguita per la richiesta dell'account, cambia solo l'url cui effettuiamo la richiesta. Per prendere confidenza con le moltiplici query che possiamo effettuare è consigliabile utilizzare il tool gratuito Data Feed Query Explorer.
Vediamo come si ottiene la stessa cosa con la GData .NET Client Library:
// Configuriamo il servizio Google di autenticazione con il nome della app
asv = new AnalyticsService("SimoneMoretti-gdataSamples-1");
// Passiamo le credenziali di accesso al servizio.
asv.setUserCredentials(TxtEmail.Text, TxtPassword.Text);
//Data Feed query uri.
String baseUrl = "https://www.google.com/analytics/feeds/data";
DataQuery query = new DataQuery(baseUrl);
query.Ids = TABLE_ID;
query.Metrics = "ga:pageviews";
query.Dimensions = "ga:pageTitle";
query.Sort = "-ga:pageviews";
query.GAStartDate = "2010-03-01";
query.GAEndDate = "2010-03-31";
query.NumberToRetrieve = 3;
query.PrettyPrint = true;
try
{
DataFeed feed = asv.Query(query); //eseguiamo la query
}
catch (AuthenticationException e)
{
// autenticazione fallita
}
catch (Google.GData.Client.GDataRequestException e)
{
// richiesta fallita
}
Usando la libreria basta creare un oggetto di tipo DataQuery
al quale passiamo la URL per la richiesta dei data feed e i parametri per raffinare la query. Chiamando il metodo Query
dell'oggetto AnalyticsService
mandiamo in esecuzione la query ed il risultato viene posto in un oggetto di tipo DataFeed.
Gestire i risultati: account feed e data feed
Una volta capito come autenticare l'utente e come effettuare la richiesta di dati non ci resta che vedere come ricevere i risultati ed usarli per i nostri scopi. Osserviamo quindi come intercettare le risposta HTTP e interpretare i risultati dell'interrogazione.
Gestire un Account Feed
Cominciamo con l'intercettare la risposta HTTP che Analytics ci invia in seguito alla richiesta di un account utente. Vediamo, nel prossimo esempio, come interpretare l'account feed ricevuto:
//myRequest è la richiesta http per l'account utente
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
Stream responseBody = myResponse.GetResponseStream();
Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
StreamReader readStream = new StreamReader(responseBody, encode);
//trasformiamo la risposta in stringa
string response = readStream.ReadToEnd();
//la risposta ha un formato XML quindi creiamo un documento XML appropriato
XmlDocument accountinfoXML = new XmlDocument(); accountinfoXML.LoadXml(response);
//per ogni profilo abbiamo un elemento entry nell'account feed
XmlNodeList entries = accountinfoXML.GetElementsByTagName("entry");
NameValueCollection profiles = new NameValueCollection();
//cicliamo su tutti gli elementi entry
for (int i = 0; i < entries.Count; i++)
{
// prendiamo l'id e il nome dei profili e mettiamoli in una collezione profiles.Add(entries.Item(i).ChildNodes[2].InnerText,
entries.Item(i).ChildNodes[6].Attributes["value"].Value);
}
La risposta HTTP viene gestita dalla classe HttpWebResponse
. L' account feed che riceviamo è in formato Atom ovvero in un formato XML quindi, per comodità, trasformiamo la risposta HTTP in stringa e creiamo un documento XML a partire dalla stringa sfruttando la classe XmlDocument
(System.Xml
).
Sappiamo che ad ogni profilo corrisponde un elemento entry dell'account feed quindi cicliamo tra i vari nodi XML di tipo entry e prendiamo i valori relativi all'id e al nome del profilo. Collochiamo, infine, queste informazioni in una collezione.
Al solito, vediamo come ottenere lo stesso risultato impiegando la GData .NET Client Library:
// Creiamo una query di tipo Account.
AccountQuery query = new AccountQuery();
// eseguiamo la query e mettiamo il risultato in un oggetto di tipo AccountFeed
AccountFeed accountFeed = asv.Query(query);
NameValueCollection profiles = new NameValueCollection();
//cicliamo su tutti gli elementi entry
for (int i = 0; i < accountFeed.Entries.Count; i++)
{
string nome =((AccountEntry)accountFeed.Entries[i]).Title;
string profileid =((AccountEntry)accountFeed.Entries[i]).ProfileId;
// prendiamo l'id e il nome dei profili e mettiamoli in una collezione
profiles.Add(profileid, nome);
}
Tutto ciò che dobbiamo fare è creare un oggetto di tipo AccountQuery
che rappresenta la richiesta di informazioni sull'account utente. Dopo di ciò dobbiamo invocare il metodo Query dell'oggetto asv di tipo AnalyticsService
e mettere il risultato della query in un oggetto di tipo AccountFeed
. Cicliamo, infine, tra le entry (ne abbiamo una per ogni profilo) e preleviamo il nome e l'identificativo dei profili per mezzo delle proprietà Title
e ProfileId
.
Gestire un Data Feed
Nella pagina precedente abbiamo visto come richiedere i dati relativi alle pagine più viste di un sito in un determinato mese. Vediamo, attraverso il seguente esempio, come intercettare la risposta http e come interpretare il data feed ricevuto:
//myRequest è la richiesta http di dati Analytics
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
Stream responseBody = myResponse.GetResponseStream();
Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
StreamReader readStream = new StreamReader(responseBody, encode);
//trasformiamo il risultato in formato stringa
results = readStream.ReadToEnd();
//creiamo un documento XML a partire dalla stringa precedente
XmlDocument resultsXML = new XmlDocument();
resultsXML.LoadXml(results);
//creiamo una lista degli oggetti entry
XmlNodeList entries = resultsXML.GetElementsByTagName("entry");
//dagli oggetti entry preleviamo il valore di dimension e metric
for (int i = 0; i < entries.Count; i++)
{
string dimension = entries[i].ChildNodes[4].Attributes["value"].Value;
string metric = entries[i].ChildNodes[5].Attributes["value"].Value;
// dimension e metric sono il titolo della pagina e il numero di visualizzazioni
Response.Write(demension + " - " + metric + "<BR>");
}
La risposta HTTP viene gestita dalla classe HttpWebResponse
. Il data feed che riceviamo è in formato Atom ovvero in un formato XML quindi per comodità del programmatore trasformiamo la risposta HTTP in stringa e creiamo un documento XML a partire dalla stringa sfruttando la classe XmlDocument
. Sappiamo che ad ogni dato corrisponde un elemento entry
del data feed quindi cicliamo tra i vari nodi XML di tipo entry
e prendiamo i valori relativi alla dimensione e alla metrica.
Ecco come ottenere lo stesso risultato impiegando la GData .NET Client Library:
// GA Data Feed query uri
String baseUrl = "https://www.google.com/analytics/feeds/data";
DataQuery query = new DataQuery(baseUrl);
query.Ids = TABLE_ID;
query.Metrics = "ga:pageviews";
query.Dimensions = "ga:pageTitle";
query.Sort = "-ga:pageviews";
query.GAStartDate = "2010-03-01";
query.GAEndDate = "2010-03-31";
query.NumberToRetrieve = 3;
query.PrettyPrint = true;
try
{
feed = asv.Query(query); //eseguiamo la query
}
catch (AuthenticationException e){ // autenticazione fallita }
catch (Google.GData.Client.GDataRequestException e){ //autenticazione fallita }
if (feed.Entries.Count != 0) //se abbiamo oggetti entry
{
for (int i = 0; i < feed.Entries.Count; i++) //cicliamo tra gli entry
{
//prendiamo dimension e metric
string dimension = ((DataEntry)feed.Entries[i]).Dimensions[0].Value;
string metric = ((DataEntry)feed.Entries[i]).Metrics[0].Value;
//dimension e metric sono il titolo della pagina e il numero di visualizzazioni
Response.Write(dimension + " - " + metric + "<BR>");
}
}
Creiamo un oggetto DataQuery
al quale passiamo i parametri Ids
, Dimensions
, Metrics
, Sort
, GAStartDate
, GAEndDate
, NumberToRetrieve
e PrettyPrint
. Eseguiamo la query e poniamo il risultato in un oggetto DataFeed
. Cicliamo tra gli oggetti Entry
del DataFeed
e prendiamo i valori delle proprietà Dimension
e Metric
.
Usare la GData .NET Client Library
La libreria mette a disposizione un insieme di classi che corrispondono agli elementi ed ai tipi di dati usati dalla GData API. Ad esempio c'è una classe Feed che corrisponde all'elemento <atom:feed>
, c'è anche una classe Entry
corrispondente all'elemento <atom:entry>
. Allo stesso modo troviamo classi Dimension
, Metric
, Segment
, DataSource
corrispondenti ad altrettanti elementi Atom.
La libreria può navigare automaticamente all'interno di una struttura Atom e creare degli oggetti corrispondenti agli elementi della struttura.
Nel capitolo 3 abbiamo presentato degli esempi che fanno vedere quanto sia semplice interagire con le GA Export API attraverso la GData .NET Client Library. Abbiamo osservato anche che le GA Export API permettono solo di leggere dati Analytics ma di non manipolarli.
Osserviamo che attraverso la GData .NET Client Library è possibile interagire non solo con le GA Export API ma con tutte le GData API riportate di seguito:
GData API supportate | ||
---|---|---|
Base |
Blogger |
|
Calendar |
Spreadsheets |
|
Google Apps Provisioning |
Code Search |
|
Notebook |
Picasa Web Albums |
|
Document Feed |
Contacts |
|
You Tube |
Google Health |
|
Google Webmaster Tools |
Molte di queste API consentono di manipolare i dati, oltre che di leggerli. GData .NET Client Library agevola questa manipolazione attraverso degli appositi metodi (insert
, update
, delete
) applicabili ad oggetti di alto livello (feed
, entry
, segment
, ecc.). Maggiori dettagli li troviamo sulla .NET Client Library Developer's Guide.
Ora ne sappiamo abbastanza su Google Analytics e sulle relative API. Nella seconda parte dell'articolo realizzeremo tre esempi che per toccare con mano le potenzialità che questi strumenti mettono a disposizione.
Email con report settimanale degli accessi al sito
Nella prima parte dell'articolo abbiamo osservato le tecniche di base per l'accesso ai dati di traffico dei nostri siti. Ora realizziamo invece alcuni esempi per toccare con mano le potenzialità di queste API.
Un servizio molto interessante che possiamo implementare è l'invio di una email con resoconto settimanale delle statistiche del sito web rivolta ad una lista di utenti:
protected void btnEmail_Click(object sender, EventArgs e)
{
string from = "webmaster@undominio.it";
string soggetto = "Resoconto Settimanale Statistiche Sito Web";
string emails = "cliente1@undominio.it, cliente2@undominio.it";
System.Net.Mail.MailMessage mail = new System.Net.Mail.MailMessage();
System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient();
mail.From = new System.Net.Mail.MailAddress(from);
mail.To.Add(emails);
mail.IsBodyHtml = true;
mail.Subject = soggetto;
mail.Body = dati();//risultato della query a Google Analytics
smtp.Host = "Smtp.undominio.it";
smtp.Send(mail);
}
Per generare l'email usiamo la classe Mail
(System.Net
), valorizziamo i campi mittente, destinatario e soggetto e nel corpo del messaggio inseriamo il risultato della nostra query a Google Analytics.
Esaminiamo il metodo dati
che richiede il totale di accessi al sito nella settimana corrente:
protected string dati()
{
// GA Data Feed query uri
String baseUrl = "https://www.google.com/analytics/feeds/data";
DataQuery query = new DataQuery(baseUrl);
query.Ids = TABLE_ID;
query.Metrics = "ga:visits";
query.Dimensions = "ga:date";
query.Sort = "ga:date";
query.GAStartDate = "2010-06-21";
query.GAEndDate = "2010-06-27";
query.PrettyPrint = true;
try
{
feed = asv.Query(query);
}
catch (AuthenticationException e)
{
//autenticazione fallita
}
catch (Google.GData.Client.GDataRequestException e)
{
//autenticazione fallita
}
return getEntriesAsTable(feed); //trasformo il DataFeed in formato stringa
}
Il risultato della query valorizza l'oggetto feed
di tipo DataFeed
. Di questo oggetto prendiamo solo i dati che ci interessano e li trasformiamo in stringhe, grazie al metodo getEntriesAsTable
, in cui iniziamo ad elaborare il messattio. Per organizzare meglio il report, introduciamo anche un po' di formattazione nel testo:
public String getEntriesAsTable()
{
if (feed.Entries.Count == 0)
{
return "Nessun entry trovato";
}
StringBuilder feedDataLines = new StringBuilder("n----- Elenco delle entry ----n");
//cicliamo tra gli oggetti entry del DataFeed
foreach (DataEntry singleEntry in feed.Entries)
{
// creiamo un array delle dimensioni
foreach (Dimension dimension in singleEntry.Dimensions)
{
String[] args = { dimension.Name, dimension.Value };
feedDataLines.AppendLine(String.Format("n{0} t= {1}", args));
}
// creiamo un array delle metriche
foreach (Metric metric in singleEntry.Metrics)
{
String[] args = { metric.Name, metric.Value };
feedDataLines.AppendLine(String.Format("n{0} t= {1}", args));
}
feedDataLines.Append("n");
}
// ritorniamo la stringa generata
return feedDataLines.ToString();
}
Cicliamo tra gli oggetti entry del datafeed, per ogni entry cicliamo tra i suoi oggetti Dimension
e Metric
ed inseriamo i valori in un oggetto StringBuilder di appoggio che alla fine trasformiamo in stringa.
Grafici con statistiche mensili degli accessi al sito
Il secondo esempio che realizziamo consiste nella creazione di grafici che mostrino le statistiche del traffico del sito.Questi report possono essere creati dinamicamente al momento della richiesta degli utenti da pagine web preposte.
Grafico lineare degli accessi
Vediamo come realizzare un grafico lineare che riporta il numero di accessi al sito nel corso di un mese:
protected string dati()
{
// GA Data Feed query uri.
String baseUrl = "https://www.google.com/analytics/feeds/data";
DataQuery query = new DataQuery(baseUrl);
query.Ids = TABLE_ID;
query.Metrics = "ga:visits";
query.Dimensions = "ga:date";
query.Sort = "ga:date";
query.GAStartDate = "2010-03-01";
query.GAEndDate = "2010-03-31";
query.PrettyPrint = true;
try { feed = asv.Query(query); }
catch (AuthenticationException e) { } // autenticazione fallita
catch (Google.GData.Client.GDataRequestException e){ } //autenticazione fallita
if (feed.Entries.Count != 0)
{
for (int i = 0; i < feed.Entries.Count; i++)
{
string giorno = ((DataEntry)feed.Entries[i]).Dimensions[0].Value;
string visite = ((DataEntry)feed.Entries[i]).Metrics[0].Value;
Chart1.Series["Serie"].Points.AddXY(giorno, visite );
//recupero il datapoint appena inserito e vi aggiungo la proprietà tooltip
System.Web.UI.DataVisualization.Charting.DataPoint dp = new System.Web.UI.DataVisualization.Charting.DataPoint();
dp = Chart1.Series["Serie"].Points[Chart1.Series["Serie"].Points.Count - 1];
dp.ToolTip = "visite: " + visite + " giorno:" + giorno;
}
}
Chart1.Visible= true;
}
Il nostro grafico ha nell'asse delle ascisse i giorni del mese e nell'asse delle ordinate il numero totale di accessi per giorno. Costruiamo il grafico usando il Chart Control. Alimentiamo il grafico con i dati provenienti dalla query rivolta al servizio remoto Google Analytics. In figura 6 possiamo vedere il grafico generato.
Per saperne di più sull'utilizzo del Chart Control è possible leggere questo articolo.
Grafico a torta dei browser dei visitatori
Un altro report tipico è quello che riproduce in un grafico a torta le visite raggruppate sui browser usati dai visitatori del sito web:
protected string dati()
{
// GA Data Feed query uri.
String baseUrl = "https://www.google.com/analytics/feeds/data";
DataQuery query = new DataQuery(baseUrl);
query.Ids = TABLE_ID;
query.Metrics = "ga:visits";
query.Dimensions = "ga:browser";
query.Sort = "ga:visits";
query.GAStartDate = "2010-03-01";
query.GAEndDate = "2010-03-31";
query.PrettyPrint = true;
try { feed = asv.Query(query); }
catch (AuthenticationException e) { } // autenticazione fallita
catch (Google.GData.Client.GDataRequestException e) { } //autenticazione fallita
if (feed.Entries.Count != 0)
{
for (int i = 0; i < feed.Entries.Count; i++)
{
string browser = ((DataEntry)feed.Entries[i]).Dimensions[0].Value;
string visite = ((DataEntry)feed.Entries[i]).Metrics[0].Value;
Chart2.Series["Serie"].Points.AddXY(browser, visite);
// recupero il datapoint appena inserito e vi aggiungo la proprietà tooltip
System.Web.UI.DataVisualization.Charting.DataPoint dp = new System.Web.UI.DataVisualization.Charting.DataPoint();
dp = Chart2.Series["Serie"].Points[Chart2.Series["Serie"].Points.Count - 1];
dp.ToolTip = "Browser = #VALXnTotale visite = #VALYnPercentuale = #PERCENT{P2}";
}
}
Chart2.Visible = true;
}
La prassi è la stessa dell'esempio precedente, eseguiamo la query al servizio Analytics e riempiamo l'oggetto Chart con i dati contenuti negli oggetti Dimension
e Metric
.
Tutti gli esempi che abbiamo esaminato sono disponibili nel file allegato all'articolo.
Conclusioni
Interrogare Google Analytics è molto semplice, grazie alle Google Analytics Data Export API. Abbiamo visto come effettuare query e ottenere i dati sotto forma di richieste e risposte HTTP (logica REST) e come sfruttare i dati ottenuti sotto forma di feed.