¿Qué tan rápido se actualizan sus datos de AdWords? Descubrir

El ex Googler Daniel Gilbert comparte un script de Brainlabs que calcula qué tan recientemente se actualizaron sus datos de AdWords.

búsqueda-computadora-analítica-datos-ss-1920

¿Alguna vez se preguntó qué tan actualizados están sus datos de AdWords?

En los viejos tiempos, los datos de AdWords podían tardar hasta un día en actualizarse. En estos días, hay una advertencia en la interfaz que dice «Es posible que no se incluyan los clics y las impresiones recibidas en las últimas tres horas». Sin embargo, hemos notado que los datos generalmente se actualizan con más regularidad. De hecho, hemos creado herramientas que responden en tiempo real, por lo que es importante saber qué tan recientes son esos datos.

Algunos de los chicos de Brainlabs (mi empleador) decidieron realizar un pequeño experimento que compartimos a continuación. Sondeamos la API de AdWords repetidamente para que podamos saber qué tan recientes son los datos. Hemos abierto el código para que pueda ejecutarlo usted mismo, pero si solo desea saber qué tan en tiempo real están nuestros datos de AdWords, consulte el gráfico en vivo que estamos actualizando. aquí.

En el momento de redactar este artículo, hemos visto AdWords:

  • Actualice cada 2:43 minutos.
  • Proporcione datos de tan solo 13:22 minutos antes.

Eso es increíblemente rápido para un sistema tan complejo. ¡Felicitaciones al fenomenal equipo de la API de AdWords! La metodología se centra en extraer un informe de las impresiones de hoy segmentadas por hora y luego compararlo con los datos del informe anterior. Puede saber con qué frecuencia se actualiza la información de la API al ver cuándo aumentan las impresiones de las horas más recientes. (Estamos analizando datos de nuestras cuentas más importantes, por lo que podemos asumir que siempre llegan impresiones).

Puede saber qué tan reciente es la información viendo cuándo aparecen los datos de la hora actual. Si no se muestran impresiones para las 11 a. M. En el informe descargado a las 11:13, pero hay impresiones para las 11 a. M. Cuando descarga un informe a las 11:14, sabrá que los datos tienen entre 13 y 14 minutos.

Si tiene acceso a la API, puede probarlo con sus propias cuentas. A continuación se muestra un script PHP para registrar cuando cambian los datos de la API. Averigua con qué frecuencia cambian sus datos de AdWords (a los 30 segundos más cercanos). Para ejecutar el script, necesitará PHP instalado y necesitará el Biblioteca cliente de la API de AdWords (con autenticación preparar).

Antes de ejecutar el script, cambie esta parte:

require_once ‘/googleads-php-lib/examples/AdWords/v201502/init.php’;

para tener la ruta del archivo init.php de la biblioteca cliente. También deberá ingresar la zona horaria de su cuenta (para que el script pueda crear fechas correctamente) y el nombre de su cuenta (usado para los nombres de archivo). También puede ingresar el ID de cliente de la cuenta, aunque esto solo es necesario si no especificó un ID de cliente al configurar la autorización.

Puedes cambiar el Hora de correr si lo desea, pero tenga en cuenta que este script es una manera fácil de agotar su cuota de informes. Si tiene acceso básico a la API, solo puede descargar 1.000 informes al día, por lo que no puede ejecutar este script durante más de nueve horas. Le sugerimos que, si tiene acceso básico, solo lo ejecute durante un par de horas para que pueda descargar cualquier otro informe que desee.

También tenga en cuenta que este proceso funciona asumiendo que la cuenta siempre obtiene impresiones; si tiene una cuenta más pequeña o si ejecuta el script en un momento en el que no hay mucho tráfico, no funcionará con tanta precisión.

El script debe crear cuatro archivos:

  • Log.csv contiene todos los datos de impresiones y clics y la hora a la que se descargó.
  • Summary.csv enumera la hora a la que se realizaron las actualizaciones y la hora desde la última actualización.
  • Hour-data.csv informa cuándo aparecieron por primera vez los datos de cada hora y cuándo cambiaron por última vez. (A veces, los datos pueden cambiar mucho después de que finalice la hora, si Google elimina las impresiones no válidas).
  • Results.txt se escribe al final y proporciona el tiempo promedio, máximo y mínimo entre actualizaciones, y la antigüedad promedio de los datos (que es el tiempo promedio entre el inicio de una hora y los datos de la hora que aparecen en los informes).

(El script también usa tempdatastore.csv mientras se está ejecutando, pero debería eliminarlo al final).

Descubrimos que los datos tienden a actualizarse cada tres minutos (aunque eso puede variar entre 1:50 y 6:00 minutos), y que los datos tienen alrededor de 14 minutos. ¿Es lo mismo para ti?

<?php

require_once '/googleads-php-lib/examples/AdWords/v201502/init.php';
require_once ADWORDS_UTIL_PATH . '/ReportUtils.php';

$accountTimezone = "Europe/London";
// Change to your account's timezone

$accountName = "Which Technology2";
// Change to your account's name

$accountId = "xxx-xxx-xxxx";
// Change to your account's customer ID, if required.

$timeToRun = "02:00:00";
// The approximate time for the script to download data.
// The default is to run for 2 hours


//////////////////////////////////////////////////////////////////////////////////
// Main body

date_default_timezone_set($accountTimezone);
$cooldown = 0;

$fileHandles = makeFileHandles();
if ($fileHandles == null) {
 // Files could not be opened, so the script cannot run
 die;
}

$AdWordsUser = new AdWordsUser();
if ($accountId != "xxx-xxx-xxxx") {
 $AdWordsUser->SetClientCustomerId($accountId);
}

// Convert $timeToRun into seconds
$timeBits = explode(":",$timeToRun);
$secondsToRun = ($timeBits[0]*60*60) + ($timeBits[1]*60) + $timeBits[2];

for ($n=0; $n 0) {
// The data was different within the last minute, so there's no point looking now
$cooldown--;
} else {
// Get the latest report, compare with the previous report.
$different = compareNewReport($AdWordsUser, $fileHandles, $n);
if ($different === true) {
// If the new data was different then there should be a cooldown period
$cooldown = 2;
}
}
// Sleep for 30 seconds, before checking again
sleep(30);
}

echo "Finished fetching data n";

// Gets final averages and outputs into the summary document.
$updateTimes = getAverageTimes($fileHandles);
$hourUpdateTime = getHourAverage($fileHandles);

$resultText = "Results of the API Update Checker for " . $accountName . " (at ". date("Y-m-d H:i:s") . ")rn"
. "Average time between updates: ".$updateTimes["avg"]. "rn"
. "Maximum time between updates: ".$updateTimes["max"]. "rn"
. "Minimum time between updates: ".$updateTimes["min"]. "rn"
. "Average age of data: " . $hourUpdateTime . "rn"
."rn";
fwrite($fileHandles["Results"],$resultText);

// Close all the file handles
foreach ($fileHandles as $name => $handle) {
fclose($handle);
}

unlink("tempdatastore.csv");

//////////////////////////////////////////////////////////////////////////////////
// Functions

function makeFileHandles() {
// Opens or creates the required files
// Returns an array containing the file handles

try {
$fileHandles = array();

if (!file_exists("log.csv")) {
$fileHandles["Log"] = fopen("log.csv","c+");
fputcsv($fileHandles["Log"],array("Date","Hour of day","Impressions","Clicks", "Time Downloaded", "Time Since Last Update"));
} else {
$fileHandles["Log"] = fopen("log.csv","c+");
}

if (!file_exists("hour-data.csv")) {
$fileHandles["Hour Data"] = fopen("hour-data.csv","c+");
fputcsv($fileHandles["Hour Data"],array("Hour of Day","Data First Appeared","Data Last Updated"));

$hour = "";
$startOfYesterday = date("Y-m-d",time() - 60 * 60 * 24)." 00:00:00";
for ($i=1; $igetMessage() . "n";
$working = false;
}

// Check the handles are working, exit if any are not
foreach ($fileHandles as $name => $handle) {
if ($handle === false) {
echo $name . " could not be opened. The file might be in use by another program. n";
$working = false;
}
}
if ($working) {
return $fileHandles;
} else {
return null;
}
} // end function makeFileHandles

function compareNewReport($AdWordsUser, $fileHandles, $n) {
// Downloads an AdWords report and compares it to the previous download
// (in the temp data store).
// If there is a difference:
// * the data is recorded in the log file
// * the newer data replaces the old in the temp data store file
// * the time of the update is recorded in the summary file
// * information on when each hour's data is updated is recorded in the hour data file
// The function returns TRUE if the most recent report was different to the last

try {
$fileSafeDate = date("H_i_s");
$fullDate = date("Ymd H:i:s");
$today = date("Ymd");
$yesterday = date("Ymd", time() - 60 * 60 * 24);

// Downloads an account performance report to get impressions and clicks by the hour, for today and yesterday
$AdWordsReportFilePath = $fileSafeDate . "_report.csv";
$reportDownloadedSuccessfully = DownloadCriteriaReport($AdWordsUser, $AdWordsReportFilePath, $yesterday, $today);
if (!$reportDownloadedSuccessfully) {
echo "Report could not be downloaded. n";
return;
}

// Reads the report
$handleAdWordsReport = fopen($AdWordsReportFilePath, "r");
$newData = array();
$j = 0;
$latestHour = "19700101 00:00:00";

if ($handleAdWordsReport === false) {
echo "Could not open report file. n";
return;
}

while(!feof($handleAdWordsReport)){
$a = fgetcsv($handleAdWordsReport);
if($j === 0){
$j = 1;
continue;
}
if($a[0] === "Total"){
break;
}

$currentHour = $a[0]." ".str_pad($a[1], 2, "0", STR_PAD_LEFT).":00:00";
$newData[$currentHour] = $a;

if (strtotime($currentHour) > strtotime($latestHour)) {
$latestHour = $currentHour;
}
}
fclose($handleAdWordsReport);
unlink($AdWordsReportFilePath);

// Read the last set of data, in $fileHandles["Temp Data Store"], and see if there are differences
$different = false;
$tempDataExists = true;
$newHourData = false;
$j = 0;
$hoursChanged = array();
rewind($fileHandles["Temp Data Store"]);
if (feof($fileHandles["Temp Data Store"])) {
$different = true;
$tempDataExists = false;
}

while(!feof($fileHandles["Temp Data Store"])) {
$a = fgetcsv($fileHandles["Temp Data Store"]);

if($a[0] === "Total" || $a[0] == ""){
if ($j === 0) {
$different = true;
$tempDataExists = false;
}
break;
}

$currentHour = $a[0]." ".str_pad($a[1], 2, "0", STR_PAD_LEFT).":00:00";

if ($j == 0 ) {
if (strtotime($latestHour) > strtotime($currentHour)) {
$newHourData = true;
echo "New hour data for " . $latestHour . "n";
$different = true;
$oldTime = strtotime($a[count($a)-1]);
$hoursChanged[] = $latestHour;
}
$j = 1;
}

if (!isset($newData[$currentHour])) {
$different = true;
$oldTime = strtotime($a[count($a)-1]);
$hoursChanged[] = $currentHour;
} else {
for ($i=1; $i 0) {
// If $n is 0, this is the first time the function has run,
// so we don't record the time difference
$timeDifference = secondsToHours($newTime - $oldTime);
}

// Read the "Hour Data" file and update if the data for an hour has changed,
// or a new hour has started
rewind($fileHandles["Hour Data"]); //get the pointer to the start of the file
while (!feof($fileHandles["Hour Data"])) {
$a = fgetcsv($fileHandles["Hour Data"]);
if (!$a) {
break;
}
if (array_search($a[0],$hoursChanged) !== false) {
$hourData[$a[0]] = array($a[0], $a[1], $fullDate);
} else {
$hourData[$a[0]] = $a;
}
}

if ($newHourData) {
foreach ($newData as $hour => $row) {
if (!isset($hourData[$hour])) {
if ($tempDataExists) {
$hourData[$hour] = array($hour, $fullDate, $fullDate);
$startHour = new DateTime($hour);
$endHour = new DateTime($fullDate);
$diffHours = $startHour->diff($endHour);
} else {
// We can't be sure that this is the earliest the hour's data appeared
// so we don't record a 'First Update' time
$hourData[$hour] = array($hour, "-", $fullDate);
}
}
} // end foreach
krsort($hourData);
}

rewind($fileHandles["Hour Data"]);
$h = 0;
foreach ($hourData as $row) {
fputcsv($fileHandles["Hour Data"], $row);
$h++;
if ($h > 48) {
break;
}
}
ftruncate($fileHandles["Hour Data"],ftell($fileHandles["Hour Data"]));

// Write the temp data store, log and summary only when there are changes
rewind($fileHandles["Temp Data Store"]);
fseek($fileHandles["Log"],0,SEEK_END);

fseek($fileHandles["Summary"],0,SEEK_END);
fputcsv($fileHandles["Summary"],array($fullDate,$timeDifference));

krsort($newData);
foreach ($newData as $hour => $row) {
$row[] = $fullDate;
fputcsv($fileHandles["Temp Data Store"],$row);
$row[] = $timeDifference;
fputcsv($fileHandles["Log"],$row);
}
ftruncate($fileHandles["Temp Data Store"],ftell($fileHandles["Temp Data Store"]));

getAverageTimes($fileHandles);
getHourAverage($fileHandles);
} else {
echo "Data is the same. n";
}

return $different;

} catch (Exception $e) {
echo $e->getMessage() . "n";
return false;
}
} // end function getNewData

function getAverageTimes($fileHandles) {
// This reads the summary file and calculates the average
// time between updates

$count = 0;
$total = 0;
$max = 0;
$min = 999999;
$output = array();

rewind($fileHandles["Summary"]);
while (!feof($fileHandles["Summary"])) {
$a = fgetcsv($fileHandles["Summary"]);
if (!empty($a[1]) && $a[1] != "-" && $a[1] != "Time Since Last Update") {
$count++;

$timeBits = explode(":",$a[1]);
$timeInSeconds = ($timeBits[0]*60*60) + ($timeBits[1]*60) + $timeBits[2];
$total += $timeInSeconds ;
if ($timeInSeconds > $max) {
$max = $timeInSeconds;
}
if ($timeInSeconds 0 && $total > 0) {
$output["avg"] = secondsToHours($total/$count);
} else {
$output["avg"] = "-";
}
if ($max > 0) {
$output["max"] = secondsToHours($max);
} else {
$output["max"] = "-";
}
if ($min 0 && $total > 0) {
$avg = secondsToHours($total / $count);
echo "Avg time for hour to appear: " . $avg ."n";
} else {
$avg = "-";
}

return $avg;
} // end function getHourAverage

function secondsToHours($secondsDifference) {
// Converts a number of seconds into a string formatted as H:i:s

return str_pad(floor($secondsDifference/3600), 2, "0", STR_PAD_LEFT) . ":" .
str_pad(floor(($secondsDifference % 3600)/60), 2, "0", STR_PAD_LEFT) . ":" .
str_pad(($secondsDifference % 60), 2, "0", STR_PAD_LEFT);
}

function DownloadCriteriaReport($AdWordsUser, $filePath, $dateRangeMin, $dateRangeMax){
// Downloads an account performance report from AdWords

try {

$reportQuery = 'SELECT Date, HourOfDay, Impressions, Clicks FROM ACCOUNT_PERFORMANCE_REPORT DURING ' . $dateRangeMin .",". $dateRangeMax;

$dateRange = array(
'min' => $dateRangeMin,
'max' => $dateRangeMax
);

$options = array('version' => ADWORDS_VERSION);

$options['skipReportHeader'] = true;
$options['skipReportSummary'] = false;

ReportUtils::DownloadReportWithAwql($reportQuery, $filePath, $AdWordsUser,
'CSV', $options);

echo "Report was downloaded. n";

return true;
} catch (Exception $e) {
printf("An error has occurred: %sn", $e->getMessage());
return false;
}
} // end function DownloadCriteriaReport

?>

Las opiniones expresadas en este artículo pertenecen al autor invitado y no necesariamente a El Blog informatico. Los autores del personal se enumeran aquí.


Deja un comentario