В работе часто использую короткую статистику в разрезе дней чтобы отслеживать отклонения трафика.
Более подробно о написании запросов написал в статье « Получение рекламных кампаний Яндекс Директ с помощью API в DataFrame (Python)».
В данной статье я в большей степени расскажу о том, как структурировать данные и запросы, чтобы этим можно было нормально пользоваться.
Нам следует прописать запрос к серверу как функцию.
Лично я сделал 2 файла: функция с запросом и файл с данными, которые будут передаваться в функцию.
Я запрашиваю по всем проектам одни и те же поля, поэтому мне нужно передавать в запрос только даты, логин и токен.
Передача данных в функцию у меня выглядит следующим образом:
Данный запрос запрашивает данные по следующим параметрам:
Примерно так:
Это делается для того, чтобы легко менять информацию по всем клиентам, и даты отчетов.
Подробнее:
![](https://habrastorage.org/r/w1560/webt/13/sh/nl/13shnl9hhylqhldqo-2svhx09-q.png)
Прописываем во втором файле все проекты, после чего у нас должна выводиться статистика по всем проектам.
После нам нужно будет лишь менять отрезок времени в полях DateFrom и DateTo.
Более подробно о написании запросов написал в статье « Получение рекламных кампаний Яндекс Директ с помощью API в DataFrame (Python)».
В данной статье я в большей степени расскажу о том, как структурировать данные и запросы, чтобы этим можно было нормально пользоваться.
Нам следует прописать запрос к серверу как функцию.
Лично я сделал 2 файла: функция с запросом и файл с данными, которые будут передаваться в функцию.
В первом файле пишем функцию
Я запрашиваю по всем проектам одни и те же поля, поэтому мне нужно передавать в запрос только даты, логин и токен.
Передача данных в функцию у меня выглядит следующим образом:
def rep(token,login,date_from,date_to):
Пишем запрос к серверу API Яндекс Директ
Данный запрос запрашивает данные по следующим параметрам:
- Date
- Impressions
- Clicks
- Ctr
- Cost
- AvgCpc
- AvgImpressionPosition
- AvgClickPosition
- AvgTrafficVolume
- BounceRate
- AvgPageviews
Конечный файл с запросом
Код
import requests
from requests.exceptions import ConnectionError
from time import sleep
import json
# Метод для корректной обработки строк в кодировке UTF-8 как в Python 3, так и в Python 2
import sys
def rep(token,login,date_from,date_to):
if sys.version_info < (3,):
def u(x):
try:
return x.encode("utf8")
except UnicodeDecodeError:
return x
else:
def u(x):
if type(x) == type(b''):
return x.decode('utf8')
else:
return x
# --- Входные данные ---
# Адрес сервиса Reports для отправки JSON-запросов (регистрозависимый)
ReportsURL = 'https://api.direct.yandex.com/json/v5/reports'
# OAuth-токен пользователя, от имени которого будут выполняться запросы
token = token
# Логин клиента рекламного агентства
# Обязательный параметр, если запросы выполняются от имени рекламного агентства
clientLogin = login
# --- Подготовка запроса ---
# Создание HTTP-заголовков запроса
headers = {
# OAuth-токен. Использование слова Bearer обязательно
"Authorization": "Bearer " + token,
# Логин клиента рекламного агентства
"Client-Login": clientLogin,
# Язык ответных сообщений
"Accept-Language": "ru",
# Режим формирования отчета
"processingMode": "auto"
# Формат денежных значений в отчете
# "returnMoneyInMicros": "false",
# Не выводить в отчете строку с названием отчета и диапазоном дат
# "skipReportHeader": "true",
# Не выводить в отчете строку с названиями полей
# "skipColumnHeader": "true",
# Не выводить в отчете строку с количеством строк статистики
# "skipReportSummary": "true"
}
# Создание тела запроса
body = {
"params": {
"SelectionCriteria": {
"DateFrom": date_from,
"DateTo": date_to
},
"FieldNames": [
"Date",
"Impressions",
"Clicks",
"Ctr",
"Cost",
"AvgCpc",
"AvgImpressionPosition",
"AvgClickPosition",
"AvgTrafficVolume",
"BounceRate",
"AvgPageviews",
],
"ReportName": u("Report4"),
"ReportType": "ACCOUNT_PERFORMANCE_REPORT",
"DateRangeType": "CUSTOM_DATE",
"Format": "TSV",
"IncludeVAT": "NO",
"IncludeDiscount": "NO"
}
}
# Кодирование тела запроса в JSON
body = json.dumps(body, indent=4)
# --- Запуск цикла для выполнения запросов ---
# Если получен HTTP-код 200, то выводится содержание отчета
# Если получен HTTP-код 201 или 202, выполняются повторные запросы
while True:
try:
req = requests.post(ReportsURL, body, headers=headers)
req.encoding = 'utf-8' # Принудительная обработка ответа в кодировке UTF-8
if req.status_code == 400:
print("Параметры запроса указаны неверно или достигнут лимит отчетов в очереди")
print("RequestId: {}".format(req.headers.get("RequestId", False)))
print("JSON-код запроса: {}".format(u(body)))
print("JSON-код ответа сервера: \n{}".format(u(req.json())))
break
elif req.status_code == 200:
format(u(req.text))
break
elif req.status_code == 201:
print("Отчет успешно поставлен в очередь в режиме офлайн")
retryIn = int(req.headers.get("retryIn", 60))
print("Повторная отправка запроса через {} секунд".format(retryIn))
print("RequestId: {}".format(req.headers.get("RequestId", False)))
sleep(retryIn)
elif req.status_code == 202:
print("Отчет формируется в режиме офлайн")
retryIn = int(req.headers.get("retryIn", 60))
print("Повторная отправка запроса через {} секунд".format(retryIn))
print("RequestId: {}".format(req.headers.get("RequestId", False)))
sleep(retryIn)
elif req.status_code == 500:
print("При формировании отчета произошла ошибка. Пожалуйста, попробуйте повторить запрос позднее")
print("RequestId: {}".format(req.headers.get("RequestId", False)))
print("JSON-код ответа сервера: \n{}".format(u(req.json())))
break
elif req.status_code == 502:
print("Время формирования отчета превысило серверное ограничение.")
print(
"Пожалуйста, попробуйте изменить параметры запроса - уменьшить период и количество запрашиваемых данных.")
print("JSON-код запроса: {}".format(body))
print("RequestId: {}".format(req.headers.get("RequestId", False)))
print("JSON-код ответа сервера: \n{}".format(u(req.json())))
break
else:
print("Произошла непредвиденная ошибка")
print("RequestId: {}".format(req.headers.get("RequestId", False)))
print("JSON-код запроса: {}".format(body))
print("JSON-код ответа сервера: \n{}".format(u(req.json())))
break
# Обработка ошибки, если не удалось соединиться с сервером API Директа
except ConnectionError:
# В данном случае мы рекомендуем повторить запрос позднее
print("Произошла ошибка соединения с сервером API")
# Принудительный выход из цикла
break
# Если возникла какая-либо другая ошибка
except:
# В данном случае мы рекомендуем проанализировать действия приложения
print("Произошла непредвиденная ошибка")
# Принудительный выход из цикла
break
json_string = json.dumps(body)
return req.text
2 Файл
Выносим даты, логины и токены отдельно как переменные.
Примерно так:
#токены
mytoken='blablablablaBLABLAsdfgsrgkdfgnf'
#логины
project = 'elama-99999999'
#Даты
DateFrom="2019-04-08"
DateTo="2019-04-16"
Это делается для того, чтобы легко менять информацию по всем клиентам, и даты отчетов.
Код для запроса статистики по проекту
print( ‘\n===Название проекта===')
data=rep(mytoken,project,DateFrom,DateTo)
file=open("cashe.csv","w")
file.write(data)
file.close()
f=DataFrame.from_csv("cashe.csv",header=1,sep=' ',index_col=0,parse_dates=True)
f['Cost']=f['Cost']*1.2
f[‘Cost']=f['Cost']/1000000
f['AvgCpc']=f['AvgCpc']*1.2
f['AvgCpc']=f['AvgCpc']/1000000
print(f)
Подробнее:
- Название проекта ("=" используем для лучшего выделения, чтобы потом не потеряться в информации)
- Data — Записываем в эту строчку переменные, которые уже обозначили выше. (эта строчка и будет выполнять первый файл)
- Записываем ответ сервера в файл
- Открываем файл как DataFrame
- Добавляем к денежным значениям НДС.
- Переводим денежные значения в обычные рубли (стандартно API использует не рубли, а рубли*1000000.
- Выводим наш DataFrame
![](https://habrastorage.org/webt/13/sh/nl/13shnl9hhylqhldqo-2svhx09-q.png)
Второй файл выглядит следующим образом:
Код
#импорты
import pandas as pd
import numpy as np
from pandas import Series,DataFrame
from НАЗВАНИЕ ФАЙЛА С ЗАПРОСОМ import rep
#Функции вывода Датафрейма
pd.set_option('display.max_columns',None)
pd.set_option('display.expand_frame_repr',False)
pd.set_option(‘max_colwidth',-1)
#токены
mytoken='blablablablaBLABLAsdfgsrgkdfgnf'
#логины
project = 'elama-99999999'
#Даты
DateFrom="2019-04-08"
DateTo="2019-04-16"
print( ‘\n===Название проекта===')
data=rep(mytoken,project,DateFrom,DateTo)
file=open("cashe.csv","w")
file.write(data)
file.close()
f=DataFrame.from_csv("cashe.csv",header=1,sep=' ',index_col=0,parse_dates=True)
f['Cost']=f['Cost']*1.2
f[‘Cost']=f['Cost']/1000000
f['AvgCpc']=f['AvgCpc']*1.2
f['AvgCpc']=f['AvgCpc']/1000000
print(f)
Прописываем во втором файле все проекты, после чего у нас должна выводиться статистика по всем проектам.
После нам нужно будет лишь менять отрезок времени в полях DateFrom и DateTo.