Это вторая статья из нашей серии о том, как использовать кастомные скрипты для автоматизации задач РРС-специалистов. В первой мы рассказали, как можно быстро удалить неявные дубли из семантического ядра. А из этой статьи вы узнаете, как за пару минут сгруппировать сотни ключевых фраз в Google Таблице с помощью простого скрипта, который сэкономит вам часы ручной работы.

Представим: семантическое ядро собрано, дубли удалены и следующий шаг – группировка ключевых фраз.

Группировка ключевых фраз – этап, на котором поисковые запросы необходимо объединить в группы по сходству. Например, фразы “купить цветы” и “купить цветы бишкек” можно отнести к одной группе, а “цветы доставка” и “доставка цветов бишкек” – к другой. Такой подход помогает подготовить рекламные объявления, максимально релевантные поисковому запросу.

Чтобы не разбирать каждый запрос вручную или через фильтры таблицы, мы подготовили скрипт, который делает за нас 90% этой работы.

Кому подойдёт

Этот скрипт создан для PPC-специалистов, SEO-аналитиков и маркетологов, которые работают с семантическими ядрами в Google Таблицах.

Что потребуется

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

Полезный скрипт от Peklo Company

Для примера возьмём тему “Отдых на Иссык-Куле”. В семантическое ядро попадут разные запросы – туры, цены на отдых, пансионаты, базы отдыха и прочее.

Пример СЯ на тему “Отдых на Иссык-Куле”

Запускаем скрипт и всего за несколько секунд он формирует нам новый лист в Google Таблице, на котором поисковые фразы уже рассортированы по общим признакам:

Пример уведомления: сколько создано групп и из скольких фраз

Пример результата работы скрипта
Среднее время выполнения даже объёмной задачи – менее минуты

Что важно знать:

  • Рекомендуем делать вычитку результатов перед тем, как добавить группы к рекламным кампаниям, чтобы убедиться, что в группу не проскочил лишний ключ.

  • При большом количестве строк с поисковыми фразами групп может быть много – это связано с детализацией разбивки результатов. Большинство из них можно вручную объединить между собой. Это займёт какое-то время, но итоговый результат всё равно будет в разы быстрее, чем без помощи скрипта.

Для данного примера: если брать полный список запросов по теме, в нём будет множество строк для отдельных пансионатов – “радуга”, “солнышко”, “звёздочка” и так далее. Скрипт сделает отдельную группу под каждый из них, и логично объединить такие группы в одну – “пансионаты”.

Ниже мы публикуем полный код скрипта. Если вы используете его в вашей работе, будем рады получить фидбек о том, сколько времени это решение сэкономило для вас.

Примечание: вы можете скорректировать скрипт под себя, изменяя настройки параметров MIN_SIMILARITY и MIN_GROUP_SIZE (первый отвечает за то, насколько схожими должны быть фразы для объединения, второй – какое минимальное количество фраз будет в группе). Выставленные настройки являются рекомендованными – при них мы получали наиболее хорошие результаты.

Код скрипта для чистки неявных дублей:

/**
 * Группирует схожие ключевые фразы в Google Таблице
 * Фразы в группе выводятся в отдельные строки
 */
function groupSimilarKeywords() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const dataRange = sheet.getDataRange();
  const data = dataRange.getValues();

  // Параметры алгоритма
  const MIN_SIMILARITY = 0.7; // Минимальный коэффициент схожести (0-1)
  const MIN_GROUP_SIZE = 2; // Минимальное количество фраз в группе

  // Извлекаем фразы и частотности
  const phrases = [];
  for (let i = 0; i < data.length; i++) {
    if (i === 0) continue; // Пропускаем заголовок, если есть
    if (data[i][0]) {
      phrases.push({
        text: data[i][0].toString().toLowerCase().trim(),
        frequency: data[i][1] ? Number(data[i][1]) : 0,
        row: i + 1
      });
    }
  }

  // Создаем группы схожих фраз
  const groups = [];
  const usedPhrases = new Set();

  for (let i = 0; i < phrases.length; i++) {
    if (usedPhrases.has(i)) continue;

    const currentPhrase = phrases[i];
    const group = [currentPhrase];
    usedPhrases.add(i);

    for (let j = i + 1; j < phrases.length; j++) {
      if (usedPhrases.has(j)) continue;

      const similarity = calculateSimilarity(currentPhrase.text, phrases[j].text);
      if (similarity >= MIN_SIMILARITY) {
        group.push(phrases[j]);
        usedPhrases.add(j);
      }
    }

    if (group.length >= MIN_GROUP_SIZE) {
      groups.push(group);
    }
  }

  // Сортируем группы по суммарной частотности
  groups.sort((a, b) => {
    const sumA = a.reduce((sum, item) => sum + item.frequency, 0);
    const sumB = b.reduce((sum, item) => sum + item.frequency, 0);
    return sumB - sumA;
  });

  // Подготавливаем данные для вывода
  const output = [];
  const header = ["Исходная фраза", "Частотность", "Группа", "Фразы в группе", "Суммарная частотность"];
  output.push(header);

  // Сначала добавляем сгруппированные фразы
  groups.forEach((group, groupIndex) => {
    const groupFrequency = group.reduce((sum, item) => sum + item.frequency, 0);

    // Для каждой фразы в группе создаем отдельную строку
    group.forEach((item, itemIndex) => {
      output.push([
        item.text,
        item.frequency,
        `Группа ${groupIndex + 1}`,
        // Для первой строки группы выводим все фразы, для остальных - пусто
        itemIndex === 0 ? group.map(g => g.text).join("\n") : "",
        itemIndex === 0 ? groupFrequency : ""
      ]);
    });
  });

  // Затем добавляем несгруппированные фразы
  phrases.forEach((phrase, index) => {
    if (!usedPhrases.has(index)) {
      output.push([
        phrase.text,
        phrase.frequency,
        "Не сгруппировано",
        "",
        phrase.frequency
      ]);
    }
  });

  // Записываем результаты на новый лист
  const resultSheetName = "Группировка фраз " + new Date().toLocaleString();
  let resultSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(resultSheetName);
  if (resultSheet) {
    resultSheet.clear();
  } else {
    resultSheet = SpreadsheetApp.getActiveSpreadsheet().insertSheet(resultSheetName);
  }

  resultSheet.getRange(1, 1, output.length, output[0].length).setValues(output);

  // Форматирование
  resultSheet.setFrozenRows(1);
  resultSheet.getRange(1, 1, 1, header.length).setFontWeight("bold");

  // Настраиваем перенос текста для столбца с фразами в группе
  resultSheet.getRange(2, 4, output.length - 1, 1).setWrap(true);

  // Автоподбор ширины столбцов
  resultSheet.autoResizeColumns(1, header.length);

  SpreadsheetApp.getUi().alert(`Готово! Создано ${groups.length} групп из ${phrases.length} фраз.`);
}

/**
 * Вычисляет схожесть между двумя фразами (0-1)
 */
function calculateSimilarity(phrase1, phrase2) {
  // Разбиваем фразы на слова
  const words1 = new Set(phrase1.split(/\s+/));
  const words2 = new Set(phrase2.split(/\s+/));

  // Находим пересечение слов
  const intersection = new Set([...words1].filter(word => words2.has(word)));

  // Находим объединение слов
  const union = new Set([...words1, ...words2]);

  // Коэффициент Жаккара
  return union.size > 0 ? intersection.size / union.size : 0;
}

Автоматизация работы при помощи кастомных скриптов

Эта задача – не единственная, которую мы решаем при помощи автоматизации. Часть полезных скриптов мы публикуем в нашем блоге в открытом доступе. Некоторые решения мы не можем показать открыто, оставляя эти наработки только для внутреннего пользования.

Если вы в своей работе сталкиваетесь с рутинными задачами в Google Таблицах, вы можете заказать у нас кастомный скрипт для автоматизации этих задач и экономии своего времени. Для этого свяжитесь с нами любым удобным способом: ссылка на все наши контакты.

Андрей Осянин
PPC Team Lead
Как автоматизировать группировку фраз из семантического ядра в Google Таблице
4 min read · Oct 17, 2025
Полезное
Вернуться в блог
отправить
Это колл-ту-экшн, друг:

CМОТРИ ВИДЕО про ПЕКЛО на нашем YouTube-канале

Бриф
Пожалуйста, выделите 3-5 минут своего времени, чтобы заполнить бриф. Это поможет нам изучить ваш бизнес перед тем, как связываться с вами. Если это вам неудобно, свяжитесь с нами напрямую.
Адрес
Кыргызская Республика, Бишкек
ул.Аалы Токомбаева 31/1, 6 этаж, кабинет 605
Контакты
Peklo Studio 2016 - 2025
Error get alias