Анализатор поисковых запросов Яндекс.Директа
Одиночный HTML-файл без серверов и подписок: загрузил CSV - получил отчёт с кандидатами в минус-слова, отказниками и KPI
Стандартный отчёт по поисковым запросам из Директа - плоская таблица на несколько тысяч строк. Найти в ней расходники без конверсий, кандидаты в минус-слова и запросы с высокими отказами - полдня работы. Roistat, K50, Adalysis решают это, но стоят 5-30 тыс. руб./мес. и требуют API-доступа к аккаунту. Хотелось аналитику без подписки и без передачи данных клиента на сторонние серверы.
Сделать инструмент для анализа CSV-выгрузки из Директа. Без бэкенда, без регистрации, без установки. Открыл HTML в браузере, загрузил CSV, получил отчёт с готовыми выводами.
Как это сделано
Архитектура: один файл - вся логика
Один HTML-файл 233 КБ - никакого сервера, никакой установки, работает на любом компьютере. Данные не уходят никуда: CSV парсится в браузере через PapaParse, результаты передаются между вкладками через localStorage. Отчёт открывается в новой вкладке через window.open() с флагом ?report=1 - тот же HTML-файл, но в режиме просмотра.
Парсинг CSV: устойчивость к форматам экспорта
Директ выгружает CSV с метаданными в первых строках - строка заголовков начинается где-то по середине. Парсер ищёт её сам (ищет "Поисковый запрос" в первых 10 строках) и вытаскивает оттуда период и имя клиента. Отдельный нюанс: в разных версиях экспорта столбец расхода разделён обычным пробелом или неразрывным (NBSP) - сделан тройной fallback. Колонки отказов и глубины просмотра опциональны: если их нет в выгрузке, инструмент не показывает соответствующие секции.
Алгоритм кандидатов в минус-слова
Каждое слово из поисковых запросов (длина >= 3, не стоп-слово, не число) получает метрики: total_cost, waste_cost (расход на клики без конверсий), количество запросов. Слово исключается, если конвертирует: total_cost/conv <= avgCPA * 1.25. Итоговый скор: waste_cost * waste_ratio^2 * (1 - min(conv_risk*5, 0.95)). Топ-50 по скору - каждое слово раскрывается в список запросов, в которых оно встречается. Кнопка "Скопировать (N)" копирует выбранные слова напрямую для вставки в Директ.
12 секций отчёта и визуализация
Отчёт строится из 12 включаемых/отключаемых секций: сводка KPI с плашкой "Потенциальные потери бюджета", категории запросов со stacked bar-диаграммой (5 цветов по типу), брендовость, тип соответствия, топ запросов (лимит 20/30/50/все), расходники без конверсий, срезы по группам и ключевым фразам, кандидаты в минус-слова из запросов и из ключей, запросы и ключи с высокими отказами. Все таблицы с sticky-шапкой, строками "Итого" и "Остальные".
Скачиваемый HTML-снапшот без JS
Кнопка "Скачать" в шапке отчёта формирует автономный HTML-документ: встроены все стили, текущая тема (dark/light) зафиксирована в data-theme, весь #report-body.innerHTML сериализован. Из JS оставлена только функция раскрытия строк минус-слов (toggleMW). Сортировка таблиц и копирование в снапшоте не работают - это намеренно: снапшот - статический артефакт для хранения и передачи клиенту, не интерактивный инструмент. Имя файла: dsq_{clientName}_{дата}.html.
Ключевые решения
Одиночный файл vs платный SaaS
Roistat / K50 / Adalysis: 5 000-30 000 руб/мес, требуют API-доступа к аккаунту, данные уходят на сторонние серверы
HTML-файл 233 КБ: 0 руб/мес, работает оффлайн, данные не покидают браузер, открывается на любом компьютере
Если анализ нужен раз в месяц или нерегулярно, платить 10-30 тыс. руб./мес. не имеет смысла. HTML-файл решает ту же задачу и не требует ничего сверху.
localStorage vs передача через URL / сервер
Передача данных между страницами через URL-параметры ограничена ~2 КБ, через сервер требует бэкенда и хранилища
localStorage (5-10 МБ): generate() сериализует state + data в JSON, новая вкладка читает их при старте - полноценная передача без сервера
CSV поисковых запросов за месяц - это 0.5-3 МБ. В URL не влезет, сервер не нужен. localStorage в том же домене - единственный вариант.
Статический снапшот vs живое приложение
Отчёт живёт только в браузере пока открыта вкладка - нельзя сохранить, отправить или открыть через месяц
Кнопка "Скачать" экспортирует самодостаточный HTML без зависимостей: открывается без интернета, пересылается клиенту, архивируется как документ
Отчёт нужен не только прямо сейчас. Через месяц его приходится показывать клиенту при согласовании бюджета, через год - смотреть на ретроспективу. HTML без зависимостей просто открывается - и всё.
Ежемесячный чек-ап рекламных кампаний теперь занимает 10 минут: выгрузил CSV из Директа, открыл инструмент, скачал отчёт. Отправляю клиенту или складываю в архив проекта. Работает без регистрации, без сервера - открыл HTML в браузере, и готово.
Частые вопросы
Директ показывает поисковые запросы списком, но не агрегирует их по словам, не выделяет кандидатов в минус-слова и не считает, сколько денег уходит вхолостую. Инструмент делает эту работу поверх тех же данных - только загрузи CSV.
Да. Файл обрабатывается целиком в браузере через PapaParse. Данные сохраняются только в localStorage вашего браузера и никуда не отправляются - у инструмента нет бэкенда.
Это сумма расходов на два типа трафика: клики без конверсий (при включённом отслеживании) и клики с высоким процентом отказов. Называть это точными "потерями" нельзя - часть такого трафика работает на охват. Но это хороший сигнал, с чего начинать оптимизацию.
Создаёт самодостаточный HTML-файл с именем dsq_{клиент}_{дата}.html. В него встроены все стили, шрифты подключены через @import, весь отображённый контент сериализован. Файл открывается без интернета (кроме шрифтов при первом открытии), его можно отправить клиенту или сохранить в архив.