Делаем свой счётчик просмотров, используя API Метрики


07-11-2018
Денис Л.
Разное
28
59116
Делаем свой счётчик просмотров, используя API Метрики

Зачем может понадобиться свой счётчик просмотров?

  1. если у Вам блог на чистом коде, либо на своей CMS;
  2. если Вы пишете приложение, в котором требуется фиксировать и показывать количество просмотров;
  3. если у Вас стоит популярная CMS, но при этом Вы не хотите использовать сторонние плагины из-за рисков безопасности и прочего;
  4. если у Вас интранет-сайт с отдельным функционалом.

Итак,

Как сделать свой счётчик, используя Яндекс.Метрика API

Я предполагаю, что у Вас уже есть свой аккаунт на Яндексе, а также установлен счётчик на сайт, поэтому об этом отдельно писать не буду.

Первым делом заходим на сервис API Метрики: https://tech.yandex.ru/metrika/. Выполняем пункт №1 - получаем OAuth-токен. Токен - это уникальный ключ для доступа к данным, который мы будем потом использовать в своём запросе для получения данных Метрики. Вводим название приложения - например, название нашего сайта.

Далее в разделе "Платформы" помечаем галочку "Веб-сервисы" и нажимаем "Подставить URL для разработки".

Затем в разделе "Доступы" ищем "Яндекс.Метрика" и отмечаем пункт "Получение статистики, чтение параметров своих и доверенных счётчиков".

Нажимаем "Создать приложение". Открывается страница, на которой мы увидим ID, пароль и Callback URL. Сохраните себе эти данные в любой файл. Из данных нас интересует только ID. Далее переходим непосредственно к получению токена.

Для этого нам нужно перейти по ссылке вида: https://oauth.yandex.ru/authorize?response_type=token&client_id=<идентификатор приложения>, где вместо <идентификатор приложения> поставляем свой ID. После формирования ссылки открываем соседнюю вкладку, вставляем нашу ссылку и нажимаем Enter. Открывается страница с вопросом разрешить ли доступ к получению статистики? Нажимаем "Разрешить".

Если на каком-либо этапе у Вас возникнут сложности - вот ссылка на официальный ресурс по получению токена: https://tech.yandex.ru/oauth/doc/dg/tasks/get-oauth-token-docpage/

Отлично! Идём далее.

Теперь нам нужно сформировать запрос, после выполнения которого мы получим ответ в формате JSON, данные из которого мы вставим в шаблон вывода поста, либо в любой другой шаблон сайта, который нам требуется. Если хотите вникнуть детально в процесс формирования url для запроса и понять все метрики и группировки - то можете почитать документацию по API Метрики. Наша же цель вполне конкретна и запрос сформирован, поэтому пропустим это. Тем не менее, я расскажу про те параметры, которые входят в наш запрос.

Например, чтобы получить количество просмотров страниц сайта, начиная с 1 января 2018 года используется запрос вида:

https://api-metrika.yandex.ru/stat/v1/data?
    &ids=XXXXXXXX                          - сюда ставим номер Вашего счётчика на Метрике
    &metrics=ym:pv:pageviews,ym:pv:users   - получаем данные по просмотренным страницам и по количеству просмотров
    &dimensions=ym:pv:URLHash              - группируем данные по URLHash (всё, что идёт после адреса сайта)
    &date1=2018-01-01                      - здесь ставим дату, от которой нам нужно вести отчёт
    &accuracy=full                         - получаем точную статистику, без округления
    &limit=100000                          - ставим максимальный лимит данных, 100 000
    &proposed_accuracy=false               - запрещаем округлять статистику, если не укажем то при большом объёме данных будет сильно округлённый результат

Вот какой ответ мы получим:

{
    "query": {
        "ids": [49714012], 
        "dimensions": ["ym:pv:URLHash"], 
        "metrics": ["ym:pv:pageviews", "ym:pv:users"], 
        "sort": ["-ym:pv:pageviews"], 
        "date1": "2018-01-01", 
        "limit": 100000, 
        "offset": 1, 
        "group": "Week", 
        "auto_group_size": "1", 
        "quantile": "50", 
        "offline_window": "21", 
        "attribution": "Last", 
        "currency": "RUB"
    }
    ,
    "data":[ {
        "dimensions":[ {
            "id": "15565728283724620474", "favicon": "blog.lisogorsky.ru", "name": "https://blog.lisogorsky.ru/javascript-protection"
        }
        ],
        "metrics":[584.0, 481.0] - количество просмотров статьи / количество уникальных посетителей статьи
    }
    ,

    ... здесь будут данные по всем остальным страницам Вашего сайта

    ],
    "total_rows":77,
    "total_rows_rounded":false,
    "sampled":false,
    "sample_share":1.0,
    "sample_size":2257,
    "sample_space":2257,
    "data_lag":104,
    "totals":[2257.0, 1025.0],
    "min":[1.0, 1.0],
    "max":[584.0, 481.0]
}

Обращаю внимание на параметр "sampled" в нижней части данных. Если Вы получаете статистику за несколько лет и у Вас много страниц на сайте, то в качестве значения должно быть указано false. Данный параметр отвечает за точность вычисления результата. Позволяет управлять семплированием (количеством визитов, использованных при расчете итогового значения). По умолчанию стоит значение medium — возвращает результат на основе выборки, сочетающей скорость и точность данных. В моём случае, на рабочем сайте данные были совершенно некорректны. Я запрашивал отчёт с параметром по умолчанию, начиная с 2016 года. Записей было много, около 100 000 и все цифры были округлённые до трёх нулей. Т.е. вместо скажем 27654 стояло 27000. Мы же получаем абсолютно точные значения, указав в нашем url параметры accuracy=full и proposed_accuracy=false. Но при запросе точных значений чуть увеличивается время запроса. Поэтому, Вам нужно понять,точные ли значения приходят конкретно в Вашем случае. Если полученные значения не отличаются от значений на сайте Метрики, то Вы можете не задавать значения точности и в url запроса вообще не использовать параметры accuracy и proposed_accuracy.

Теперь нам осталось обработать полученные данные и вставить их в наши записи.

Создаём отдельный файл, скажем ya_metrika.php и в него пишем код для скачивания к нам на сервер данных Метрики:

<?php
$options = array('http' => array('method' => 'GET', 'header' => array("Content-Type: application/x-yametrika+json", "Authorization: OAuth ВАШ_ОТЛАДОЧНЫЙ_ТОКЕН_ЗДЕСЬ")));
$context = stream_context_create($options);
$url = 'https://api-metrika.yandex.ru/stat/v1/data?&ids=НОМЕР_ВАШЕГО_СЧЁТЧИКА_МЕТРИКИ&metrics=ym:pv:pageviews,ym:pv:users&dimensions=ym:pv:URLHash&date1=ДАТА_НАЧИНАЯ_С_КОТОРОЙ_МЫ_ХОТИМ_ПОЛУЧИТЬ_ДАННЫЕ&accuracy=full&limit=100000&proposed_accuracy=false';
$metrikaRequest = file_get_contents($url, false, $context);
if(!empty($metrikaRequest)) file_put_contents("ПОЛНЫЙ_ПУТЬ_К_ФАЙЛУ_В_КОТОРЫЙ_БУДЕМ_ЗАПИСЫВАТЬ_ДАННЫЕ_НАПРИМЕР: /home/bitrix/www/metrika.json", $metrikaRequest);
?>

Обратите внимание на места кода, где Вам потребуется вставить свои данные (выделены маркером).

Делаем файл исполняемым (даём ему права 0755).

По итогам выполнения запроса мы получим данные, которые сохраняться в файл JSON, путь на который мы с Вами указывали выше.

Ставим планировщик на выполнение файла ya_metrika.php, скажем один раз в час. Т.е. один раз в час наш скрипт будет обращаться к серверу Метрики и обновлять наши данные. Можете сделать и чаще (раз в полчаса или 15 минут), но имейте ввиду, что есть ограничение по количеству запросов в месяц (5000).

Но сперва давайте протестируем работу нашего запроса.

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

/usr/bin/php ПОЛНЫЙ_ПУТЬ_К_ФАЙЛУ_СКРИПТА_НАПРИМЕР: /home/bitrix/www/ya_metrika.php

В первой части команды /usr/bin/php мы говорим, что используем интерпретатор PHP для запуска команды. Во второй части (после пробела) мы указываем путь на исполняемый файл. По итогу выполнения команды, у Вас по пути к файлу JSON (который Вы указали ранее) должен появиться файл с данными. Если он появился - значит команда работает корректно. Если нет - пробуем ещё один вариант команды:

/usr/bin/wget -O /dev/null -q "http://ПУТЬ_НА_ФАЙЛ_НАПРИМЕР: /ya_metrika.php"

В результате мы получаем нужный файл с данными в нужной для нас папке. Чтобы скачивание файла происходило автоматически в заданный интервал времени (например, раз в час), задаём планировщик командой:

crontab -e

После нажатия Enter откроется редактор файлов по умолчанию. Нажимаем латинскую букву i, чтобы перейти в режим правки. Вставляем строку запуска команды:

@hourly /usr/bin/php ПОЛНЫЙ_ПУТЬ_К_ФАЙЛУ_СКРИПТА_НАПРИМЕР: /home/bitrix/www/ya_metrika.php

Или вариант строки запуска команды №2:

@hourly /usr/bin/wget -O /dev/null -q "http://ПУТЬ_НА_ФАЙЛ_НАПРИМЕР: /ya_metrika.php"

Для сохранения файла нажмите сначала Esc, затем пишем двоеточие и буквы wq. В нижней строке должно получиться :wq. Нажимаем Enter. Если всё сделали правильно, то редактор закроется и Вы увидите сообщение: crontab: installing new crontab.

P.S. Для запуска один раз в 15 минут вместо @hourly укажите */15 * * * *

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

Далее нам нужно определиться, как нам выводить данные на страницу. Есть два варианта:

  1. Показывать данные сразу, при загрузке страницы (это подходит в том случае, если размер JSON файла небольшой, скажем, до 100 Кб);
  2. Показывать данные позже, когда они будут обработаны и готовы к выводу (это нужно, если у Вас получился большой файл с данными. Например, на моём проекте файл с данными весит 1,7 Мб и нельзя было позволять скрипту тратить много времени на скачивание и обработку информации)

Если наш файл с данными небольшой и мы хотим всё показывать при загрузке страницы (вариант 1), используем PHP. Открываем файл шаблона вывода отдельного поста и пишем код:

<?php
$statisticData = $_SERVER['DOCUMENT_ROOT'].'/metrika.json'; // укажите здесь точный путь к файлу с данными на Вашем сервере
$statistic = file_get_contents($statisticData); // записываем в переменную данные из нашего файла
$countPeopleView = json_decode($statistic,true)['data']; // преобразуем в массив JSON данные
$summCountPeople = 0;
foreach($countPeopleView as $value) { // проходимся циклом по данным
    // в моём случае я проверяю вхождение в строку массива название моей записи
    // в Вашем случае Вам нужно провести свою проверку, чтобы отсортировать данные
    // например, сравнивается строка "https://blog.lisogorsky.ru/javascript-protection" со строкой "/javascript-protection"
    if(strpos($value['dimensions'][0]['name'], $postID) !== false) {
        $summCountPeople += $value['metrics'][0]; // получаем количество просмотров конкретной записи
    }
}
?>

Затем вставляем в html-код полученное значение:

<div title="Просмотров статьи"><img src="ПУТЬ_НА_КАРТИНКУ_С_ИКОНКОЙ" alt=""><?=$summCountPeople?></div>

Если файл с данными большой (вариант 2), то используем JavaScript:

document.addEventListener("DOMContentLoaded", function() { // событие загрузки страницы
    var locationUrl = window.location.pathname; // определяем текущий URL без домена и http
    setTimeout(function() { // задаём небольшой таймаут в 100 мс, чтобы не тормозить работу браузера
        var xmlhttpMetrika = new XMLHttpRequest(); // формируем новый XMLHttpRequest
        xmlhttpMetrika.onreadystatechange = function() {
            if(this.readyState == 4 && this.status == 200) {
                var metrikaData = JSON.parse(this.responseText)['data']; // переводим данные из JSON в вид ассоциативного массива
                var summCountPeople = 0;
                // ниже мы с помощью регулярного выражения проверяем вхождение в данные Метрики текущего URL
                // Ваше регулярное выражение может немного отличаться. Тестируйте через сервис https://regexr.com/
                if(locationUrl.slice(-1) == '/') {
                    var regExpForMetrika = new RegExp('(\\/\\/ваш_домен_без_http\\.ru\\'+locationUrl.substring(0,locationUrl.length-1)+'\\/)($|\\?.*)');
                } else {
                    var regExpForMetrika = new RegExp('(\\/\\/ваш_домен_без_http\\.ru\\'+locationUrl+')($|\\?.*)');
                }
                metrikaData.forEach(function(elem) {
                    if(regExpForMetrika.test(elem['dimensions'][0]['name'])) {
                        summCountPeople += elem['metrics'][0];
                    }
                })
                var countElem = document.createElement('div'); // создаём новый элемент для вставки на страницу
                countElem.className = 'countPeople'; // присваиваем элементу класс countPeople
                countElem.innerHTML = '<img src="ПУТЬ_НА_КАРТИНКУ_С_ИКОНКОЙ"><i>'+summCountPeople+'</i>'; // добавляем иконку "глаза"
                if(summCountPeople > 0) { // показываем счётчик, только если количество просмотров больше нуля
                    document.querySelector("ЭЛЕМЕНТ_СТРАНИЦЫ_КУДА_ВСТАВЛЯЕМ_ДАННЫЕ").appendChild(countElem); // вставляем на страницу
                }
            }
        };
        xmlhttpMetrika.open("GET", "ПУТЬ_НА_ФАЙЛ metrika.json", true);
        xmlhttpMetrika.send();
    },100);
});

Проверим корректность данных. Зайдём в веб-интерфейс Метрики, Отчёты --> Стандартные отчёты --> Содержание --> Популярное. Именно здесь визуально мы можем просмотреть все те же цифры по посещаемости любой конкретной страницы сайта.

Поздравляю! Теперь на сайте есть счётчик просмотров Ваших статей!

Подписывайтесь на группу в ВКонтакте, вступайте в сообщество на Facebook, чтобы всегда быть в курсе актуальных выпусков
Web development blog!

Читайте также:

Пишем свой css фреймворк на Sass

Как подключить чат в поиске Яндекса + крутой онлайн чат для сайта

Пишем функцию лайков для постов блога