Цапля

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

Если отчеты из Метрики требуется делать регулярно и для нескольких счетчиков, то править каждый раз исходный код .R файла неудобно. Программа, кратко описанная в предыдущей записи о генерации отчетов с помощью API Метрики и R, может быть дополнена.

Вспомним пару моментов: 1 — в рамках данной задачи мы пользуемся только GET-запросами; 2 — формат запроса: http://api-metrika.yandex.ru/[имя_метода].[формат_результата]?[параметры]; 3 — авторизационный токен передаётся обязательно в каждом запросе (в нашем примере он сохранен в переменную appToken).

Получаем список всех счетчиков на аккаунте

Получим данные из отчета о счетчиках, существующих на аккаунте, сохраним в переменную counters. Без указания дополнительных входных данных будут показаны вообще все счетчики, существующие на аккаунте (не зависимо от их статуса и владельца).

Запомним количество счетчиков (counters$rows). Оно нужно, чтобы вывести список всех счетчиков для выбора.

Сократим вложенность: counters<-counters$counters.

Из всего отчета нас интересует о каждом счетчике — его id (counters$id), какому домену сооветствует (counters$site), название счетчика, если вам удобнее ориентироваться по нему (counters$name) и статус (counters$code_status). Статус владельца нас не интересует, так как прочесть данные из отчетов Метрики может и не владелец счетчика.

Выведем нумерованный список доменов, для которых у нас есть счетчики, и предложим ввести в консоль порядковый номер нужного домена. Таким образом получим counterID, для которого далее будем строить отчет.


#get counterID
req<-paste("http://api-metrika.yandex.ru/counters.json?oauth_token=", appToken, sep="")
counters<-fromJSON(txt=req)
rows<-as.integer(counters$rows)
counters<-counters$counters
counters_data<-data.frame(num=1:rows, site=counters$site)
counters_data$id<-counters$id
counters_data$name<-counters$name
counters_data$status<-counters$code_status
ask_for_counter<-as.character()
for (i in 1:rows) {
ask_for_counter<-paste(ask_for_counter, "[", i, "] - ", counters_data[i,][,"site"], "\n", sep="")
}
ask_for_counter<-paste(ask_for_counter, "Choose counter, specify the index: ", sep="")
read_num<-as.integer(readline(prompt=ask_for_counter))
counterID<-counters_data[read_num,][,"id"]

Выбираем отчетный месяц

Если мы хотим построить месячный отчет, то в консоли достаточно указать год (4цифры) и месяц (2цифры). Получив эти две цифры, мы должны сконструировать date1 и date2, который будем передавать в запросе к API Метрики как даты начала периода выборки и окончания периода выборки для отчета. Причем date1 и date2 должны иметь формат YYYYMMDD.


#get date
ask_for_year<-as.character("Year (4 numbers): ")
read_year<-as.character(readline(prompt=ask_for_year))
ask_for_month<-as.character("Month (2 numbers): ")
read_month<-as.character(readline(prompt=ask_for_month))

gen_day2<- function(mon, year) {
if(mon=="01" | mon=="03" | mon=="05" | mon=="07" | mon=="08" | mon=="10" | mon=="12") {
day2<-31
return(day2)
} else if(mon=="04" | mon=="06" | mon=="09" | mon=="11") {
day2<-30
return(day2)
} else if(mon=="02") {
if(as.integer(year)%%4==0) {
day2<-29
} else { day2<-28 }

} else {
print("Wrong number specified, cannot calculate day2")


}

mons_years<-paste(read_month, "-", read_year, sep="")
date1<-paste(read_year, read_month, "01", sep="")
date2<-paste(read_year, read_month, as.character(gen_day2(read_month, read_year)), sep="")

Сравнить данные

Кроме того, что мы хотим получить данные за выбранный месяц, мы хотим сравнить сводку посещаемости с тремя предыдущими месяцами и с тем же месяцем в прошлом году. Значит, нам нужны date1 и date2 для этих периодов тоже.

В результате мы сформируем 2 массива: dates1 содержит 4 даты начала периодов выборки, dates2 содержит 4 даты в формате YYYYMMDD окончаний периодов выборки.


#generate prev_date1 and prev_date2 for comparing
prev_year<-as.character(as.integer(read_year)-1)
prev_date1<-character()
prev_date2<-character()
if (as.integer(read_month)>3) {
prev_months<-c(as.character(as.integer(read_month)-1), as.character(as.integer(read_month)-2), as.character(as.integer(read_month)-3))
for (i in 1:length(prev_months)) {
if(as.integer(prev_months[i])<10) {
prev_months[i]<-paste("0", prev_months[i], sep="")
}
prev_date1<-c(prev_date1, paste(read_year, prev_months[i], "01", sep=""))
prev_date2<-c(prev_date2, paste(read_year, prev_months[i], as.character(gen_day2(prev_months[i])), sep=""))
mons_years<-c(mons_years, paste(prev_months[i], "-", read_year, sep=""))
}

} else if(as.integer(read_month)==3) {
prev_months<-c("02", "01", "12")
prev_date1<-c(prev_date1, paste(read_year, prev_months[1], "01", sep=""), paste(read_year, prev_months[2], "01", sep=""), paste(prev_year, prev_months[3], "01", sep=""))
prev_date2<-c(prev_date2, paste(read_year, prev_months[1], as.character(gen_day2(prev_months[1])), sep=""), paste(read_year, prev_months[2], as.character(gen_day2(prev_months[2])), sep=""), paste(prev_year, prev_months[3], as.character(gen_day2(prev_months[3])), sep=""))
mons_years<-c(mons_years, paste(prev_months[1], "-", read_year, sep=""), paste(prev_months[2], "-", read_year, sep=""), paste(prev_months[3], "-", prev_year, sep=""))
} else if(as.integer(read_month)==2) {
prev_months<-c("01", "12", "11")
prev_date1<-c(prev_date1, paste(read_year, prev_months[1], "01", sep=""), paste(prev_year, prev_months[2], "01", sep=""), paste(prev_year, prev_months[3], "01", sep=""))
prev_date2<-c(prev_date2, paste(read_year, prev_months[1], as.character(gen_day2(prev_months[1])), sep=""), paste(prev_year, prev_months[2], as.character(gen_day2(prev_months[2])), sep=""), paste(prev_year, prev_months[3], as.character(gen_day2(prev_months[3])), sep=""))
mons_years<-c(mons_years, paste(prev_months[1], "-", read_year, sep=""), paste(prev_months[2], "-", prev_year, sep=""), paste(prev_months[3], "-", prev_year, sep=""))
} else if(as.integer(read_month)==1) {
prev_months<-c("12", "11", "10")
prev_date1<-c(prev_date1, paste(prev_year, prev_months[1], "01", sep=""), paste(prev_year, prev_months[2], "01", sep=""), paste(prev_year, prev_months[3], "01", sep=""))
prev_date2<-c(prev_date2, paste(prev_year, prev_months[1], as.character(gen_day2(prev_months[1])), sep=""), paste(prev_year, prev_months[2], as.character(gen_day2(prev_months[2])), sep=""), paste(prev_year, prev_months[3], as.character(gen_day2(prev_months[3])), sep=""))
mons_years<-c(mons_years, paste(prev_months[1], "-", prev_year, sep=""), paste(prev_months[2], "-", prev_year, sep=""), paste(prev_months[3], "-", prev_year, sep=""))
}
prev_date1<-c(prev_date1, paste(prev_year, read_month, "01", sep=""))
prev_date2<-c(prev_date2, paste(prev_year, read_month, as.character(gen_day2(read_month)), sep=""))
mons_years<-c(mons_years, paste(read_month, "-", prev_year, sep=""))

#vectors of all date1 and date2 values
dates1<-c(date1, prev_date1)
dates2<-c(date2, prev_date2)

Некоторых данных для построения отчета не будет

Если вы запросите отчет по целям за месяц, когда цели не были настроены, то никаких данных в отчете не будет. И если вы собирались провести сравнения или подсчеты, то может возникнуть ошибка. Поэтому, отсутствие данных надо предусмотреть и как-то обрабатывать. Например, выводить в отчете сообщение «нет информации».

Допустим, мы хотим сформировать отчет о целях по источникам.
req<-paste("http://api-metrika.yandex.ru/stat/sources/summary.json?id=", counterID, "&goal_id=", counter_goals[byrows,][,"id"], "&date1=", date1, "&date2=", date2, "&oauth_token=", appToken, sep="")
sources_summary_for_goal<-fromJSON(txt=req)
sources_summary_for_goal<-sources_summary_for_goal$data

Далее проверим, не пуст ли отчет: length(sources_summary_for_goal)!=0. Если не пуст, то работаем данными. Если пуст, то выводим сообщение о том, что требуемых данных за указанный период нет.

Файл консольного приложения на R для построения месячных отчетов с помощью API metrika на github.