В работе часто использую короткую статистику в разрезе дней чтобы отслеживать отклонения трафика.
Более подробно о написании запросов написал в статье « Получение рекламных кампаний Яндекс Директ с помощью API в DataFrame (Python)».
В данной статье я в большей степени расскажу о том, как структурировать данные и запросы, чтобы этим можно было нормально пользоваться.
Нам следует прописать запрос к серверу как функцию.
Лично я сделал 2 файла: функция с запросом и файл с данными, которые будут передаваться в функцию.
Я запрашиваю по всем проектам одни и те же поля, поэтому мне нужно передавать в запрос только даты, логин и токен.
Передача данных в функцию у меня выглядит следующим образом:
Данный запрос запрашивает данные по следующим параметрам:
Примерно так:
Это делается для того, чтобы легко менять информацию по всем клиентам, и даты отчетов.
Подробнее:

Прописываем во втором файле все проекты, после чего у нас должна выводиться статистика по всем проектам.
После нам нужно будет лишь менять отрезок времени в полях 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

Второй файл выглядит следующим образом:
Код
#импорты 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.
