Google Analytics — обходим семплирование и собираем сырые данные


image
Привет!

Если у вас посещаемый сайт (более 500 тысяч сессий за отчетный период) или вы строите какие-то сложные отчеты через интерфейс (сегментирование, подключение дополнительных параметров, частое изменение отчетного периода) — Google Analytics начинает экономить свои ресурсы и включает семплирование данных. Подробности хорошо описаны в официальной справке. То есть, чтобы подготовить вам отчёт, берутся не все данные, а какая-то часть, например 30%, и потом пропорционально показатели подгоняются под 100% и отображаются у вас в отчете.

Конечно, в таких случаях будет расхождение по количеству оплат, суммам транзакций и в количестве конверсий. Проверить легко — сравнить с цифрами из базы данных или CRM.

Избежать проблемы легко — подключить Google Analytics 360, но дорого.
Давайте научимся собирать сырые данные, используя бесплатный Google Analytics.

// эта инструкция — не решение всех ваших проблем, знакомимся с технологией!


Как строятся отчеты в Google Analytics


Чтобы отобразить отчеты в интерфейсе Google Analytics (далее GA), происходит следующее: сбор данных, обработка данных, формирование отчета.

image

Сбор данных
По протоколу Measurement Protocol GA собирает информацию о всех взаимодействиях: просмотры страниц, пользовательские события, транзакции.

Обработка информации
На основании полученной информации о взаимодействиях (просмотры страниц, другие события) GA:
  • разделяет их на сессии: если разница между взаимодействиями больше 30 минут (при базовых настройках),
  • рассчитывает кол-во просмотров на сессию, показатель отказов,
  • достаёт информацию об источниках из utm-меток и так далее,
  • Применяет фильтры, если вы их настраивали на уровне представления.

Формирование отчета
Когда вы открываете отчет через веб-интерфейс GA или по API, в зависимости от выбранного отчета, система достает данные из хранилища и возвращает информацию.

Как GA собирает данные — техническая сторона


Вы добавляете код, который предоставляет вам GA, или создаете тег через Google Tag Manager.

Когда этот код срабатывает в браузере пользователя, создается объект ga с трекером. Далее через этот трекер фиксируется взаимодействие — просмотр страницы.
Фиксируется взаимодействие, значит отправляется информация на сервер Google Analytics используя Measurement Protocol.

Если максимально упростить: информация на сервер GA передается через GET-запрос формата:

https://www.google-analytics.com/collect?v=1&_v=j67&a=1998834664&t=pageview&_s=1&dl=https%3A%2F%2Fhabrahabr.ru%2Ftop%2F&ul=en-us&de=UTF-8&dt=%D0%9B%D1%83%D1%87%D1%88%D0%B8%D0%B5%20%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D0%B8%20%D0%B7%D0%B0%20%D1%81%D1%83%D1%82%D0%BA%D0%B8%20%2F%20%D0%A5%D0%B0%D0%B1%D1%80%D0%B0%D1%85%D0%B0%D0%B1%D1%80&sd=24-bit&sr=1920x1080&vp=1841x341&je=0&_u=SCCAgEADQ~&jid=&gjid=&cid=2098823486.1505375017&tid=UA-726094-1&_gid=1797204180.1524028566&cd1=habrauser&cd2=other&cd4=no&z=1479651106


Можете открыть в браузере Панель для разработчиков, вкладка Network, сделать фильтр по слову “collect” и посмотреть подробную информацию по запросу.

image

То есть, через Query String в Google Analytics передаются данные:

v:1
_v:j50
a:643761009
t:pageview
_s:1
dl:https://habrahabr.ru/
ul:en-us
de:UTF-8
dt:Лучшие публикации за сутки / Хабрахабр
sd:24-bit
sr:1920x1080
vp:1109x966
je:0
fl:25.0 r0
_u:QCCAgEAB~
jid:1630561303
cid:774042187.1492148509
tid:UA-726094-1
cd1:guest
cd4:no
cd5:other
z:1998272259

Также каждый запрос сопровождается передачей ip-адреса, реферера, информацией о user agent.

Любые другие взаимодействия: события, транзакции также отправляются через этот трекер. То есть, трекер один и через него отправляется информация о всех взаимодействиях (стандартные + те, которые вы настроили самостоятельно).

Собираем сырые данные


Мы уже разобрались, как GA отправляет себе данные. Было бы здорово дублировать эти данные и сохранять их себе в хранилище.

Написать парсер, который будет собирать все параметры, которые собирает Google Analytics, подключить ко всем событиям… Нет, никаких велосипедов!

Прежде чем отправить информацию, скрипт GA выполняет серию заданий. Как раз отправка информации на сервер — это одно из заданий. И к нашей радости, эти задания можно модифицировать — отправлять данные не только в Google, но и на произвольный URL.

Как это сделать


Выберите вариант, через который у вас подключен счетчик Google Analytics:

Analytics.js
Стандартный код установки analytics.js имеет вид:
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

ga('create', 'UA-XXXXXXXXX-X', 'auto');
		
ga('send', 'pageview');
</script>


Дорабатываем задание customTask, в итоге получается:
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

ga('create', 'UA-XXXXXXXXX-X', 'auto');
	
// определяем customTask
ga('set', 'customTask', function(tracker) {
  // Сохраняем стандартную функцию sendHitTask.
  var originalSendHitTask = tracker.get('sendHitTask');
  
  // Вносим изменения в функцию sendHitTask
  tracker.set('sendHitTask', function(model) {
	// отправляем стандартный запрос на  www.google-analytics.com/collect
	originalSendHitTask(model); 
  
       // создаем новый запрос для отправки в своё хранилище
	var custom_tracking_url = 'ССЫЛКА НА ВАШ ПРИНИМАЮЩИЙ СКРИПТ',
	    hitPayLoad = '?' + model.get('hitPayload'),
	    user_agent = '&user_agent='+ encodeURIComponent(navigator.userAgent),
           referrer = '&referrer='+encodeURIComponent(document.referrer);
		
	var final_tracking_url = custom_tracking_url + hitPayLoad + user_agent + referrer
		document.createElement("img").src = final_tracking_url;
   });
});

	
ga('send', 'pageview');
</script>



Google Tag Manager
Нужно создать переменную customTask типа Custom JavaScript:

function () {
    return  function(tracker) {
	  // Сохраняем стандартную функцию sendHitTask.
	  var originalSendHitTask = tracker.get('sendHitTask');
	  
         // Вносим изменения в функцию sendHitTask
	  tracker.set('sendHitTask', function(model) {
		// отправляем стандартный запрос на  www.google-analytics.com/collect
		originalSendHitTask(model); 
		  
		// создаем новый запрос для отправки в своё хранилище
		var custom_tracking_url = 'ССЫЛКА НА ВАШ ПРИНИМАЮЩИЙ СКРИПТ',
		    hitPayLoad = '?' + model.get('hitPayload'),
		    user_agent = '&user_agent='+ encodeURIComponent(navigator.userAgent),
		    referrer = '&referrer='+encodeURIComponent(document.referrer);
		
		var final_tracking_url = custom_tracking_url + hitPayLoad + user_agent + referrer
		document.createElement("img").src = final_tracking_url;
	  });
	}
}


Теперь нужно к вашему тегу Universal Analytics добавить поле customTask со значением {{ customTask }}:

image



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

Настройка хранилища


Для простоты я в качестве хранилища возьму Таблицы Гугл. Конечно, для большого количества данных это вообще не вариант. Но мы тут с технологией знакомимся, поэтому для примера подойдет.

Создаем таблицу, задаем имена колонкам. Имена должны соответствовать названию параметров из Query String, которые будет отправлять трекер Google Analytics:

image

Открываем редактирование скриптов:



Добавляем скрипт, который при каждом GET-запросе будет парсить Query String и добавлять значения в таблицу:

function doGet(e) {
    record_data(e);
}

var SCRIPT_PROP = PropertiesService.getScriptProperties();

function setup() {
    var doc = SpreadsheetApp.getActiveSpreadsheet();
    SCRIPT_PROP.setProperty("key", doc.getId());
}

function record_data(e) {
  try {
    var doc     = SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"));
    var sheet   = doc.getSheetByName('Sheet1'); // select the responses sheet
    var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
    var nextRow = sheet.getLastRow()+1; // get next row
    var row     = [ new Date() ]; // first element in the row should always be a timestamp
    // loop through the header columns
    for (var i = 1; i < headers.length; i++) { // start at 1 to avoid Timestamp column
      if(headers[i].length > 0) {
        if(!e.parameter[headers[i]]) {
          e.parameter[headers[i]] = '';
        }
        row.push(e.parameter[headers[i]]); // add data to row
      }
    }
    sheet.getRange(nextRow, 1, 1, row.length).setValues([row]);
  }
  catch(error) {
    Logger.log(e);
  }
  finally {
    return;
  }

}


Запускаем функцию setup() и даем доступы на выполнение скрипта:



В опции “Who has access to the app” выбираем “Anyone, even anonymous”.

В итоге вы получите ссылку вашего Web App:



Скопируйте ссылку и перенесите ее в скрипт CustomTask, в переменную custom_tracking_url.

Теперь при всех настроенных взаимодействиях данные будут попадать не только в GA, но и в ваше хранилище.



Посмотрите как это работает в реалтайме:
  1. Откройте таблицу.
  2. Откройте тестовый сайт.
  3. Походите по сайту + следите за обновлениями в таблице.


Не все данные


Так как некоторые данные (например, IP-адрес) прилетают не через гет параметр, а в заголовках запроса можно их парсить на стороне принимающего скрипта.

С source / medium — тоже можно поработать, достать его из Pageurl и раскидать по разным колонкам.

На этом останавливаться не будем, думаю, что мысль понятна.

Зачем это всё?


  • Избавляемся от семплирования при построении отчетов.
  • Теперь нет ограничений на кастомные поля: что нужно отправляйте/получайте/взаимодействуйте.
  • Можно использовать эти данные, как условия для триггеров: просмотры страниц, совершение действия. Сопоставляем с имейлом и отправляем письма/пуши.
  • Для системы рекомендаций: также интересуются/покупают.
  • Анализируйте поведение пользователей: как они ходят по вашему сайту, в разрезе каждой сессии и вообще, за все время!
  • Анализируйте источники трафика, смотрите последовательности, каналы, которые ведут к конверсиям.
  • Отслеживайте мошенников в CPA-сетях. Тут вы увидите внезапные переходы, например, когда человек просто учит новые Слова в тренажере, а страница перезагружается и проставляются партнерские куки.
  • И сказка для маркетологов — кастомные списки ремаркетинга. Выделяете сегмент по поведению, выгружайте cid и отправляйте в GA.


Смотрите также




+ приятный бонус:
новым пользователям EnglishDom дарю бесплатный доступ на три месяца изучения английского с помощью онлайн-курсов. Перейдите по ссылке и активируйте промокод.




К сожалению, не доступен сервер mySQL