Core Reporting API: руководство для разработчиков

В этой статье описывается доступ к данным Google Analytics с помощью Core Reporting API.

Введение

Core Reporting API обеспечивает доступ к табличным данным в стандартных и специальных отчетах Google Analytics посредством запроса, в котором задаются следующие элементы: представление (профиль), даты начала и окончания, а также параметры и показатели, определяющие структуру таблицы. В ответе Core Reporting API возвращает данные в форме таблицы.

Если вы ещё не знакомы с Core Reporting API, прочитайте эту статью.

Подготовка к работе

В этой статье описывается порядок доступа к Google Analytics API с использованием языков программирования Java, Python, PHP и JavaScript programming languages.

  • Клиентские библиотеки. На этой странице представлены клиентские библиотеки для всех языков программирования, которые поддерживает этот API.
  • Справочное руководство по интерфейсу API и доступу к данным без использования клиентских библиотек.

В каждой библиотеке реализован один служебный объект Google Analytics, который обеспечивает доступ ко всем данным Core Reporting API. Чтобы создать объект службы, обычно нужно выполнить следующие действия:

  1. Зарегистрируйте приложение в Google API Console.
  2. Разрешите доступ к Google Analytics.
  3. Создайте объект службы Google Analytics.

Если вы не выполнили эти действия, перед продолжением прочитайте вводное руководство по Google Analytics API, в котором описывается, с чего нужно начинать создание приложения на его основе. После этого вы сможете применять полученные знания в реальных условиях.

Следующий фрагмент содержит переменную для хранения авторизованного объекта службы.

Java

Analytics analytics = // Read Hello Analytics Tutorial for details.

Python

analytics = # Read Hello Analytics Tutorial for details.

PHP

$client = // Read Hello Analytics Tutorial for details.

// Return results as objects.
$client->setUseObjects(true);

$analytics = new apiAnalyticsService($client);

Библиотека PHP возвращает все результаты API в виде ассоциативного массива. Чтобы получить фактические объекты, можно вызвать метод клиента useObject, показанный в предыдущем примере.

JavaScript

<script src="https://apis.google.com/js/client.js?onload=loadLib"</script>
<script>
function loadLib() {
  // Handle all the authorization work.
  // Read Hello Analytics Tutorial for details.
  gapi.client.load('analytics', 'v3', makeApiCall);
}
</script>

Первый тег этого скрипта загружает библиотеку JavaScript для Google API, после чего метод loadLib загружает класс службы Google Analytics. После этих действий в модели DOM должен появиться объект gapi.client.analytics, с помощью которого можно выполнять запросы к Core Reporting API.

Приложение использует созданный объект службы Google Analytics для выполнения запросов к Core Reporting API.

Примечание. Объект службы Google Analytics также можно использовать для доступа к Management API.

Обзор

Общий процесс работы приложения, использующего Core Reporting API, можно разбить на два этапа:

  • выполнение запроса к Core Reporting API;
  • обработка результатов API.

Рассмотрим их поподробнее.

Выполнение запроса к Core Reporting API

Создание запроса к Core Reporting API

В объекте службы Analytics представлен метод для создания запроса к Core Reporting API.

В каждом таком запросе задается набор параметров, определяющих возвращаемые данные.

Важнейшим из них является идентификатор таблицы, ids, указывающий на представление (профиль) Google Analytics, из которого требуется извлечь данные. Он имеет формат ga:xxx, где xxx – это идентификатор представления (профиля).

Java

Get apiQuery = analytics.data().ga()
    .get(tableId,                  // Table Id.
        "2012-01-01",              // Start date.
        "2012-01-15",              // End date.
        "ga:sessions")               // Metrics.
    .setDimensions("ga:source,ga:keyword")
    .setSort("-ga:sessions,ga:source")
    .setFilters("ga:medium==organic")
    .setMaxResults(25);

Python

api_query = service.data().ga().get(
    ids=TABLE_ID,
    start_date='2012-01-01',
    end_date='2012-01-15',
    metrics='ga:sessions',
    dimensions='ga:source,ga:keyword',
    sort='-ga:sessions,ga:source',
    filters='ga:medium==organic',
    max_results='25')

PHP

private function queryCoreReportingApi() {
  $optParams = array(
      'dimensions' => 'ga:source,ga:keyword',
      'sort' => '-ga:sessions,ga:source',
      'filters' => 'ga:medium==organic',
      'max-results' => '25');

  return $service->data_ga->get(
      TABLE_ID,
      '2010-01-01',
      '2010-01-15',
      'ga:sessions',
      $optParams);
}

Метод get из этой библиотеки не только создает запрос к Core Reporting API, но и выполняет его.

JavaScript

function makeApiCall() {
  var apiQuery = gapi.client.analytics.data.ga.get({
    'ids': TABLE_ID,
    'start-date': '2010-01-01',
    'end-date': '2010-01-15',
    'metrics': 'ga:sessions',
    'dimensions': 'ga:source,ga:keyword',
    'sort': '-ga:sessions,ga:source',
    'filters': 'ga:medium==organic',
    'max-results': 25
  });
  // ...
}

В этом примере после загрузки клиентской библиотеки JavaScript вызывается функция makeApiCall, которая создает новый запрос Google Analytics API и сохраняет этот объект в переменной apiQuery.

Полный список параметров запроса и описание их действия вы найдете в справке по Core Reporting API. С помощью параметров и показателей вы можете определить данные, которые будут извлечены иGoogle Analytics. Полный список параметров и показателей вы найдете здесь.

Запрос данных с помощью Core Reporting API

Чтобы отправить запрос на серверы Google Analytics, вызовите метод execute.

Java

try {
  apiQuery.execute();
  // Success. Do something cool!

} catch (GoogleJsonResponseException e) {
  // Catch API specific errors.
  handleApiError(e);

} catch (IOException e) {
  // Catch general parsing network errors.
  e.printStackTrace();
}

Если не нужно выполнять синтаксический анализ возвращаемого API ответа, используйте метод executeUnparsed():

HttpResponse response = apiQuery.executeUnparsed();

Python

try:
  results = get_api_query(service).execute()
  print_results(results)

except TypeError, error:
  # Handle errors in constructing a query.
  print ('There was an error in constructing your query : %s' % error)

except HttpError, error:
  # Handle API service errors.
  print ('There was an API error : %s : %s' %
         (error.resp.status, error._get_reason()))

PHP

  try {
    $results = queryCoreReportingApi();
    // Success. Do something cool!

  } catch (apiServiceException $e) {
    // Handle API service exceptions.
    $error = $e->getMessage();
  }

JavaScript

function makeApiCall() {
  // ...

  apiQuery.execute(handleCoreReportingResults);
}

function handleCoreReportingResults(results) {
  if (!results.error) {
    // Success. Do something cool!
  } else {
    alert('There was an error: ' + results.message);
  }
}

В этом примере выполняется запрос к Core Reporting API, созданный на предыдущем шаге. Параметр метода execute определяет ссылку на функцию обратного вызова, которая выполняется после того, как API вернет данные.

В случае ошибки в результатах будет возвращено свойство error.

Его наличие свидетельствует о возникновении проблем при выполнении.

Если запрос выполнен успешно, API возвращает данные, а в случае ошибки – соответствующий код статуса и ее описание. Во всех приложениях необходимо реализовать перехват и обработку ошибок.

Обработка результатов API

В случае успешного выполнения запроса к Core Reporting API возвращаются данные отчетов Google Analytics и связанные с ними метаданные.

Данные отчетов Google Analytics

API возвращает таблицу с двумя основными типами данных:

  • заголовок, описывающий тип значений в столбцах;
  • строки данных.

Данные заголовка столбца

Каждый ответ API содержит поле заголовка в виде списка или массива, каждый объект которого описывает тип данных в столбце. Столбцы показателей следуют за столбцами параметров в том порядке, который был определен в исходном запросе.

Java

private void printColumnHeaders(GaData gaData) {
 System.out.println("Column Headers:");

 for (GaDataColumnHeaders header : gaData.getColumnHeaders()) {
   System.out.println("Column Name: " + header.getName());
   System.out.println("Column Type: " + header.getColumnType());
   System.out.println("Column Data Type: " + header.getDataType());
 }
}

Python

def print_column_headers():
  headers = results.get('columnHeaders')

  for header in headers:
    # Print Dimension or Metric name.
    print 'Column name = %s' % header.get('name'))
    print 'Column Type = %s' % header.get('columnType')
    print 'Column Data Type = %s' % header.get('dataType')

PHP

private function printColumnHeaders(&results) {
  $html = '';
  $headers = $results->getColumnHeaders();

  foreach ($headers as $header) {
    $html .= <<<HTML
Column Name = {$header->getName()}
Column Type = {$header->getColumnType()}
Column Data Type = {$header->getDataType()}
HTML;

  print $html;
}

JavaScript

function printColumnHeaders(results) {
  var output = [];

  for (var i = 0, header; header = results.columnHeaders[i]; ++i) {
    output.push(
        'Name        = ', header.name, '\n',
        'Column Type = ', header.columnType, '\n',
        'Data Type   = ', header.dataType, '\n'
    );
  }

  alert(output.join(''));
}

Данные строк

Запрашиваемые данные возвращаются в виде двухмерного списка строк (List). Внешний список представляет все строки данных, а каждый внутренний – отдельную строку, порядок ячеек в которой соответствует заголовку столбца.

Данные возвращаются в строковой форме, и для их синтаксического анализа используется поле DataType в соответствующем объекте заголовка. Подробнее о поддерживаемых типах данных

Следующий код выводит заголовки и строки таблицы.

Java

private void printDataTable(GaData gaData) {
 if (gaData.getTotalResults() > 0) {
   System.out.println("Data Table:");

   // Print the column names.
   for (GaDataColumnHeaders header : gaData.getColumnHeaders()) {
     System.out.format("%-32s", header.getName() + '(' + header.getDataType() + ')');
   }
   System.out.println();

   // Print the rows of data.
   for (List<String> rowValues : gaData.getRows()) {
     for (String value : rowValues) {
       System.out.format("%-32s", value);
     }
     System.out.println();
   }
 } else {
   System.out.println("No Results Found");
 }

Python

def print_data_table(results):
  # Print headers.
  output = []
  for header in results.get('columnHeaders'):
    output.append('%30s' % header.get('name'))
  print ''.join(output)

  # Print rows.
  if results.get('rows', []):
    for row in results.get('rows'):
      output = []
      for cell in row:
        output.append('%30s' % cell)
      print ''.join(output)
  else:
    print 'No Results Found'

PHP

private function printDataTable(&$results) {
  if (count($results->getRows()) > 0) {
    $table .= '<table>';

    // Print headers.
    $table .= '<tr>';

    foreach ($results->getColumnHeaders() as $header) {
      $table .= '<th>' . $header->name . '</th>';
    }
    $table .= '</tr>';

    // Print table rows.
    foreach ($results->getRows() as $row) {
      $table .= '<tr>';
        foreach ($row as $cell) {
          $table .= '<td>'
                 . htmlspecialchars($cell, ENT_NOQUOTES)
                 . '</td>';
        }
      $table .= '</tr>';
    }
    $table .= '</table>';

  } else {
    $table .= '<p>No Results Found.</p>';
  }
  print $table;
}

JavaScript

function printRows(results) {
  output = [];

  if (results.rows && results.rows.length) {
    var table = ['<table>'];

    // Put headers in table.
    table.push('<tr>');
    for (var i = 0, header; header = results.columnHeaders[i]; ++i) {
      table.push('<th>', header.name, '</th>');
    }
    table.push('</tr>');

    // Put cells in table.
    for (var i = 0, row; row = results.rows[i]; ++i) {
      table.push('<tr><td>', row.join('</td><td>'), '</td></tr>');
    }
    table.push('</table>');

    output.push(table.join(''));
  } else {
    output.push('<p>No Results Found</p>');
  }

  alert(output.join(''));
}

Информация об отчете

Помимо основных данных, API возвращает общую информацию об ответе, которую можно вывести с помощью следующего кода:

Java

private void printResponseInfo(GaData gaData) {
  System.out.println("Contains Sampled Data: " + gaData.getContainsSampledData());
  System.out.println("Kind: " + gaData.getKind());
  System.out.println("ID:" + gaData.getId());
  System.out.println("Self link: " + gaData.getSelfLink());
}

Python

def print_response_info(results):
  print 'Contains Sampled Data = %s' % results.get('containsSampledData')
  print 'Kind                  = %s' % results.get('kind')
  print 'ID                    = %s' % results.get('id')
  print 'Self Link             = %s' % results.get('selfLink')

PHP

private function printReportInfo(&$results) {
  $html = <<<HTML
  <pre>
Contains Sampled Data = {$results->getContainsSampledData()}
Kind                  = {$results->getKind()}
ID                    = {$results->getId()}
Self Link             = {$results->getSelfLink()}
</pre>
HTML;

  print $html;
}

JavaScript

function printReportInfo(results) {
  var output = [];

  output.push(
      'Contains Sampled Data  = ', results.containsSampledData, '\n',
      'Kind                   = ', results.kind, '\n',
      'ID                     = ', results.id, '\n',
      'Self Link              = ', results.selfLink, '\n');

  alert(output.join(''));
}

Поле containsSampledData содержит сведения о том, использовалась ли в ответе API выборка. Как правило, она является основной причиной расхождений между значениями, возвращаемыми из API и веб-интерфейса. Подробнее...

Информация о представлении (профиле)

В каждом ответе указываются аккаунт, веб-ресурс и представление (профиль), которым принадлежат данные.

Java

private void printProfileInfo(GaData gaData) {
  GaDataProfileInfo profileInfo = gaData.getProfileInfo();

  System.out.println("Account ID: " + profileInfo.getAccountId());
  System.out.println("Web Property ID: " + profileInfo.getWebPropertyId());
  System.out.println("Internal Web Property ID: " + profileInfo.getInternalWebPropertyId());
  System.out.println("View (Profile) ID: " + profileInfo.getProfileId());
  System.out.println("View (Profile) Name: " + profileInfo.getProfileName());
  System.out.println("Table ID: " + profileInfo.getTableId());
}

Python

def print_profile_info(result):

  info = results.get('profileInfo')
  print 'Account Id          = %s' % info.get('accountId')
  print 'Web Property Id     = %s' % info.get('webPropertyId')
  print 'Web Property Id     = %s' % info.get('internalWebPropertyId')
  print 'View (Profile) Id   = %s' % info.get('profileId')
  print 'Table Id            = %s' % info.get('tableId')
  print 'View (Profile) Name = %s' % info.get('profileName')

PHP

private function printProfileInformation(&$results) {
  $profileInfo = $results->getProfileInfo();

  $html = <<<HTML
<pre>
Account ID               = {$profileInfo->getAccountId()}
Web Property ID          = {$profileInfo->getWebPropertyId()}
Internal Web Property ID = {$profileInfo->getInternalWebPropertyId()}
Profile ID               = {$profileInfo->getProfileId()}
Table ID                 = {$profileInfo->getTableId()}
Profile Name             = {$profileInfo->getProfileName()}
</pre>
HTML;

  print $html;
}

JavaScript

function printProfileInfo(results) {
  var output = [];

  var info = results.profileInfo;
  output.push(

      'Account Id          = ', info.accountId, '\n',
      'Web Property Id     = ', info.webPropertyId, '\n',
      'View (Profile) Id   = ', info.profileId, '\n',
      'Table Id            = ', info.tableId, '\n',
      'View (Profile) Name = ', info.profileName);

  alert(output.join(''));
}

Идентификаторы, определяющие объекты иерархии Management API, можно использовать в запросах к Management API для получения дополнительных сведений о конфигурации представления (профиля). Например, вы можете запросить активные цели и их названия.

Информация о запросе

Каждый ответ Core Reporting API содержит объект со всеми значениями параметров, на основе которых был создан запрос.

Java

private void printQueryInfo(GaData gaData) {
  GaDataQuery query = gaData.getQuery();

  System.out.println("Ids: " + query.getIds());
  System.out.println("Start Date: " + query.getStartDate());
  System.out.println("End Date: " + query.getEndDate());
  System.out.println("Metrics: " + query.getMetrics()); // List
  System.out.println("Dimensions: " + query.getDimensions());
  System.out.println("Sort: " + query.getSort()); // List
  System.out.println("Segment: " + query.getSegment());
  System.out.println("Filters: " + query.getFilters());
  System.out.println("Start Index: " + query.getStartIndex());
  System.out.println("Max Results: " + query.getMaxResults());
}

Python

def print_query_info(results):
  query = results.get('query')
  for key, value in query.iteritems():
    print '%s = %s' % (key, value)

PHP

private function printQueryParameters(&$results) {
  $query = $results->getQuery();

  $html = '<pre>';
  foreach ($query as $paramName => $value) {
    $html .= "$paramName = $value\n";
  }
  $html .= '</pre>';

  print $html;
}

JavaScript

function printQuery(results) {
  output = [];

  for (var key in results.query) {
    output.push(key, ' = ', results.query[key], '\n');
  }

  alert(output.join(''));
}

В отличие от остальных строковых параметров, параметры metrics и sort возвращаются в виде списка значений.

Информация о разбиении на страницы

Запросу Core Reporting API могут соответствовать сотни тысяч строк Google Analytics, однако за один раз возвращается ограниченный набор или страница . Чтобы извлечь все данные, используйте поля разбиения на страницы.

Java

private void printPaginationInfo(GaData gaData) {
  System.out.println("Items Per Page: " + gaData.getItemsPerPage());
  System.out.println("Total Results: " + gaData.getTotalResults());
  System.out.println("Previous Link: " + gaData.getPreviousLink());
  System.out.println("Next Link: " + gaData.getNextLink());
}

Python

def print_pagination_info(results):
  print 'Items per page = %s' % results.get('itemsPerPage')
  print 'Total Results  = %s' % results.get('totalResults')
  print 'Previous Link  = %s' % results.get('previousLink')
  print 'Next Link      = %s' % results.get('nextLink')

PHP

private function getPaginationInfo(&$results) {
  $html = <<<HTML
<pre>
Items per page = {$results->getItemsPerPage()}
Total results  = {$results->getTotalResults()}
Previous Link  = {$results->getPreviousLink()}
Next Link      = {$results->getNextLink()}
</pre>
HTML;

  print $html;
}

JavaScript

function printPaginationInfo(results) {
  var output = [];

  output.push(
      'Items Per Page = ', results.itemsPerPage, '\n',
      'Total Results  = ', results.totalResults, '\n',
      'Previous Link  = ', results.previousLink, '\n',
      'Next Link      = ', results.nextLink, '\n');

  alert(output.join(''));
}

В поле totalResults указывается общее количество строк Google Analytics, соответствующих вашему запросу. Количество строк, возвращаемых на одной странице ответа, может быть меньше и представлено полем itemsPerPage.

Параметры previousLink и nextLink существуют только при наличии предыдущей или следующей страницы соответственно и свидетельствуют о возможности извлечь дополнительные данные из Core Reporting API.

Сводные данные по всем результатам

Вы уже знаете, что запросу к Core Reporting API может соответствовать большое количество строк с данными Google Analytics, однако возвращаться могут не все из них. Итоговые значения показателей для всех соответствующих строк возвращаются в объекте totalsForAllResults и могут использоваться для расчета средних значений.

Java

private void printTotalsForAllResults(GaData gaData) {
  Map totalsMap = gaData.getTotalsForAllResults();

  for (Map.Entry entry : totalsMap.entrySet()) {
    System.out.println(entry.getKey() + " : " + entry.getValue());
  }
}

Python

def print_totals_for_all_results(results):
  totals = results.get('totalsForAllResults')

  for metric_name, metric_total in totals.iteritems():
    print 'Metric Name  = %s' % metric_name
    print 'Metric Total = %s' % metric_total

PHP

private function printTotalsForAllResults(&$results) {
  $totals = $results->getTotalsForAllResults();

  foreach ($totals as $metricName => $metricTotal) {
    $html .= "Metric Name  = $metricName\n";
    $html .= "Metric Total = $metricTotal";
  }

  print $html;
}

JavaScript

function printTotalsForAllResults(results) {
  var output = [];

  var totals = results.totalsForAllResults;
  for (metricName in totals) {
    output.push(
        'Metric Name  = ', metricName, '\n',
        'Metric Total = ', totals[metricName], '\n');
  }

  alert(output.join(''));
}

Готовые примеры

Готовые примеры для Core Reporting API представлены в каталоге примеров для каждой соответствующей клиентской библиотеки.