Цапля

Генерация отчетов из api metrika с помощью R

С тех пор, как появилась Яндекс.Метрика и я узнала про API, меня всегда грела мысль, что уж когда-нибудь все эти отчеты будут генериться с нажатием пары кнопок. Да, отчеты полезны, пока их делаешь, еще раз снимаешь контрольные показатели сайта, это как отойти на пару шагов и взглянуть на картину целиком. Но всё же это рутина, и если отчет генерируется нажатием кнопки, возможность взглянуть на картину издалека остаётся.

R поможет сделать с данными гораздо больше, чем просто собрать и поместить в отчет, поскольку специально создан для работы со статистикой. Однако, начнем с простого — построим отчет с данными о сайте за месяц с использование API Яндекс.Метрики.

Регистрация приложения

  • Переходим на страницу: https://oauth.yandex.ru/client/new
  • Вводим название приложения
  • Выбираем в пункте «Права» > Яндекс.Метрика. Далее ставим галочку: «Получение статистики, чтение параметров своих и доверенных счётчиков». Теперь мы сможем пользоваться только методом GET для получения данных с помощью API, а для отчета нам большего не надо.
  • Callback URI задаём: https://oauth.yandex.ru/verification_code?dev=true

    Этот callback URI предлагается использовать разработчикам на стадии отладки своего приложения, чтобы временно снять проблему организации авторизации. API Метрики использует протокол OAuth (полезная иллюстрация того, как он работает: http://api.yandex.ru/oauth/doc/dg/concepts/authorization-scheme.xml), как многие другие известные API. Есть специальный пакет для R, он называется «httr«, в нём организована поддержка авторизации приложений и получения токена для twitter api, facebook api, linkedin api, github api и др., но для Метрики нет. Впрочем, без этого можно обойтись.

После того, как приложение зарегистрировано, для него генерируется id и пароль. Теперь нужно вручную получить токен, следуем инструкции: http://api.yandex.ru/oauth/doc/dg/tasks/get-oauth-token.xml.

Создаем .R файл, например, «generate-report.R»

Метрика отдаёт данные в формате XML по умолчанию, в таком случае понадобится пакет «XML». Если использовать JSON (что, на мой взгляд, проще), то нужен пакет «jsonlite«.

  • Подключаем библиотеки, которые понадобятся:
    library(httr)
    library(jsonlite)
    library(utils)
    library(stringr)
  • Устанавливаем рабочую директорию.
    setwd("G:/Reports/")
  • Зафиксируем id приложения (например, в переменную appId), пароль (например, в переменную appSecret), токен (например, в переменную appToken), с которым будем работать, а также для простоты на данном этапе зафиксируем номер счетчика и date1 (начальная дата для построения отчета), date2 (конечная дата для построения отчета).
  • Создаем файл отчета с названием на основе даты отчета.

    Файл отчета будет сохранен в формате .html, поскольку этот формат откроется на любом компьютере и сохранит форматирование.

    R позволяет сохранять файлы в формате .txt, .xls, .pdf, .md и других. Но в случае с .html проще всего организовать форматирование, а также минимизировать проблему того, что файл не открывается или открывается некорректно.

    Можно положиться на форматирование по умолчанию организованное в браузере. Но при желании можно вставить свои стили. Сделать это можно так:

    • Создать файл со стилями (например, «report-style.css» и не забудьте поставить кодировку «UTF-8-BOM» — в notepad++ эта кодировка называется «UTF-8 (без BOM)»)
    • С помощью функции readLines() сохранить вектор строк, прочитанных из файла «report-style.css»
    • Склеить элементы вектора в одну строку с помощью функции str_c из пакета «stringr»
    • Далее с помощью функции paste() мы просто вставим эту строку между тэгами <style>
    date<-as.Date(date2, format="%Y%m%d")
    date<-as.POSIXlt(date)
    <-readLines("report-style.css", encoding="UTF-8-BOM", warn=F)
    x<-str_c(x, sep="\n", collapse="")
    headerInFile<-paste("<html><meta charset='utf-8'><style>", x, "</style><title>Сводка данных статистики по сайту</title><h1>Сводка за ", date$mon+1,"-й месяц ", date$year-100+2000, " года</h1>", sep="")


    filename<-paste(date$mon+1, " - ", date$year-100+2000, " report.html", sep="")

    if(!file.exists(filename)) {
    writeLines(text=headerInFile, con=filename)
    } else {
    print("This report has already been prepared.")
    }

Получаем данные из метрики

Справочник запросов к Метрике: http://api.yandex.ru/metrika/doc/ref/reference/metrika-api-resources.xml

Рассмотрим два примера.

Первый — получение данных отчета /stat/traffic/summary

На странице описания запроса http://api.yandex.ru/metrika/doc/ref/stat/traffic-summary.xml указано, какие параметры обязательные и необязательные можно передать (см. раздел «Входные данные»).

Сгенерируем текст запроса и сохраним в переменную req.

req<-paste("http://api-metrika.yandex.ru/stat/traffic/summary.json?id=", counterID, "&date1=", date1, "&date2=", date2, "&group=month&oauth_token=", appToken, sep="")

Запросим и сохраним данные в объект traffic_summary, который будет типа list.

traffic_summary<-fromJSON(txt=req)

Далее берем нужные данные из объекта traffic_summary и составляем строки для отчета с помощью функции paste(). Эти строки сперва записываем в переменные, которые будут типа character, а затем вставляем в файл отчета с помощью функции cat(), у которой указываем значения аттрибутов sep="\n" (разделять переменные, записываемые в файл переносом строки) и append=TRUE (не перезаписывать содержимое файла, а присоединить к уже записанному).

traffic_summary_visitors<-paste("<p>Посетителей за месяц: ", traffic_summary$totals$visitors, "</p>", sep="")

traffic_summary_visits<-paste("<p>Они совершили визитов: ", traffic_summary$totals$visits, "</p>", sep="")

traffic_summary_page_views<-paste("<p>Они просмотрели страниц: ", traffic_summary$totals$page_views, "</p>", sep="")


cat(traffic_summary_visitors, traffic_summary_visits, traffic_summary_page_views, "\n", file=filename, sep="\n", append=T)
Второй — получение данных отчета /stat/sources/sites

Параметры, которые можно передать в запросе, указаны на странице http://api.yandex.ru/metrika/doc/ref/stat/sources-sites.xml

Сгенерируем текст запроса и сохраним в переменную req.

req<-paste("http://api-metrika.yandex.ru/stat/sources/sites.json?id=", counterID, "&date1=", date1, "&date2=", date2, "&table_mode=plain&per_page=10&oauth_token=", appToken, sep="")

Запросим и сохраним данные в объект sources_sites, который будет типа list.

sources_sites<-fromJSON(txt=req)

Допустим, мы хотим извлечь адреса сайтов и количество визитов, полученных с них за рассматриваемый период. Сохраним data frame, который является элементом списка (list) sources_sites и называется "data".

sources_sites<-sources_sites[["data"]]

Создаём data.frame sources_sites_visits с первым столбцом, содержащим url'ы сайтов.

sources_sites_visits<-data.frame(Source=sources_sites$name, stringsAsFactors=F)

Добавляем колонку с количеством визитов.

sources_sites_visits$Visits<-sources_sites$visits

Задаём адреса колонок для data.frame с сайтами и визитами

colnames(sources_sites_visits)<-c("Адрес сайта", "Визиты")

Записываем в файл отчета таблицу, полученную из data.frame с сайтами и визитами

sources_sites_colnames<-colnames(sources_sites_visits)
write("<table>", file=filename, append=T)

cat("<tr><th>", sources_sites_colnames[1], "</th><th>", sources_sites_colnames[2], "</th></tr>", file=filename, sep="", append=T)

for(by_rows in 1:nrow(sources_sites_visits)) {

cat("<tr><td>", sources_sites_visits[by_rows,][,1], "</td><td>", as.character(sources_sites_visits[by_rows,][,2]), "</td></tr>", file=filename, sep="", append=T)

}
write("</table>", file=filename, append=T)

В конце не забываем закрыть тэг <html> в файле отчета. Хотя ошибки не будет, если его не закрыть, потому что правила html5 разрешают не закрывать некоторые тэги.