ГлавнаяSEO-кейсыVolagratis
Travel Международный UK / EU Programmatic SEO

SEO-кейс: как мы сделали 1 миллион продуктовых страниц

Volagratis — один из крупнейших тревел-агрегаторов в Европе. У них огромная база предложений: билеты, отели, туры. Но проблема была в другом — трафик стагнировал, поисковики индексировали сайт плохо, а конкурентные страницы забирали спрос.

Решили проблему радикально — собрали миллион продуктовых страниц. Они заполнили выдачу и начали приносить органический трафик. Ниже — как спроектировали структуру, оптимизировали индексацию и не получили штрафов за дубли.

КлиентVolagratis
НишаTravel-агрегатор
РынкиUK и Европа
ФорматProgrammatic SEO
Результат за 16 месяцев
7.74M
кликов в Google
570M
показов
245K
страниц в индексе
1.4%
средний CTR
Главная метрика
7.74M кликов

570 млн показов за 16 месяцев — programmatic SEO в travel с полной структурой сайта

Цели проекта

Задача была не «написать много текстов», а проверить гипотезу: можно ли масштабировать органику через programmatic SEO в travel — и при этом не сломать индексацию и конверсию.

  • Протестировать массовую генерацию контента. Проверить, как автоматизированное создание продуктовых страниц влияет на трафик и индексацию.
  • Закрепить лидерство в органике. Усилить позиции по ключевым запросам, чтобы конкуренты остались за бортом.
  • Оптимизировать конверсию. Превратить видимость в заявки.
  • Снизить зависимость от платного трафика. Перенести фокус с контекста на долгосрочный SEO-эффект.

Сбор ядра: как мы нашли максимум трафика

Проанализировали всю выдачу тревел-рынка UK/EU. Посмотрели не только частотные запросы, но и редкие, локальные, сезонные. Разобрали, как пользователи ищут билеты, отели и туры.

Вскрыли конкурентов: Kayak, Skyscanner, Booking, Google Flights. Изучили, какие сценарии поиска у них работают, и добавили свои гипотезы. Собрали полную карту намерений.

Учли не только запросы вроде «Как дешевле?», но и те, которые никто не закрывает — «Когда лучше ехать?», «Что посмотреть?», «Как сэкономить?». Сайт перехватывает трафик на всех этапах принятия решения.

Пример группировки

Фрагмент семантической карты: запрос → тип намерения → контекст → пример → объём.

Query Intent Type Context Example Query Volume
Рим — Барселона билетыTransactionalПользователь ищет конкретные билетыКупить билет Рим Барселона50 000
Дешевые билеты в МиланInformational / TransactionalПользователь ищет выгодную цену на билетыДешевые билеты Милан июнь40 000
Лучшие пляжи в 50 км от БарселоныInformationalПользователь ищет отдых рядом с городомЛучшие пляжи Барселона 202525 000
Лучшее время для поездки в ПарижInformationalПользователь планирует путешествиеКогда лучше лететь в Париж30 000
Горящие туры в ЛондонTransactionalПользователь ищет туры с выгодными ценамиГорящие туры Лондон март 202535 000
Топ-10 мест в Париже за 3 дняInformationalПользователь планирует короткое путешествиеЧто посмотреть в Париже за 3 дня45 000
Как добраться из аэропорта в центр МиланаInformationalПользователь ищет логистическую информациюКак доехать из аэропорта Милана до центра20 000
Отели 5 звезд в Дубае с бассейномTransactionalПользователь выбирает отель по характеристикамЛучшие 5-звездочные отели Дубай с бассейном15 000
Рейтинг отелей в Шарм-эль-ШейхеInformationalПользователь сравнивает варианты проживанияЛучшие отели Шарм-эль-Шейх отзывы10 000
Туры на Мальдивы с питанием all-inclusiveTransactionalПользователь ищет пакетные турыЛучшие туры на Мальдивы all inclusive22 000
Где поесть в Риме недорогоInformationalПользователь ищет недорогие заведенияЛучшие недорогие рестораны Рим12 000
Куда поехать на уикенд в ЕвропеInformationalПользователь ищет идеи для короткого отдыхаЛучшие города для уикенда в Европе18 000
Сколько стоит аренда авто в БарселонеTransactionalПользователь оценивает стоимость аренды автоПрокат авто Барселона цена 20258 000
Какие документы нужны для поездки в СШАInformationalПользователь уточняет визовые требованияДокументы для поездки в США 20259 000
Какой чемодан можно взять в ручную кладь RyanairInformationalПользователь уточняет правила перевозки багажаРучная кладь Ryanair размер и вес7 500

Как мы создали 1 000 000 страниц в Excel через ChatGPT и выгрузили их в CMS

Собрали таблицу с 25 колонками для гибкой генерации контента. Каждая строка — готовая страница: URL, мета-теги, текст, данные о маршруте, FAQ, разметка и приоритет индексации. Тексты генерировали через GPT API, данные о ценах и отелях — из API авиакомпаний и Booking.

URL
Ссылка на страницу
H1
Заголовок первого уровня (динамически генерируется)
Title
SEO-заголовок до 60 символов
Meta Description
Мета-описание до 160 символов
Body
Основной текст страницы (GPT API)
Departure City
Город отправления
Arrival City
Город прибытия
Country
Страна назначения
Region
Регион / область в стране
Best Travel Time
Оптимальный период для поездки
Price Range
Диапазон цен на билеты (API авиакомпаний)
Airlines
Список авиакомпаний на маршруте
Hotel Offers
Цены на отели (Booking API)
Attractions
Топовые достопримечательности (LSI-фразы)
FAQ
Частые вопросы из People Also Ask
Internal Links
Связанные внутренние ссылки (автогенерация)
Schema.org
Product + AggregateRating
Images
Изображения с автоматическими именами файлов
Reviews
Количество отзывов (Trustpilot / Google Reviews)
CTA
Призыв к действию: «Купить билет», «Забронировать отель»
Load Speed
Скорость загрузки (Lighthouse)
Indexing Priority
Приоритет индексации: High, Medium, Low
Canonical
Канонический URL (динамическое заполнение)
Structured Data Type
Product, FAQ, BreadcrumbList
Cache Control
Политика кеширования: max-age=3600, no-cache

Масштаб упирается не в «нагенерить и забыть», а в шаблон с уникальными переменными, canonical на каждую страницу и приоритетная индексация. Так миллион URL не превращается в миллион дублей.

Генерация контента

Контент генерировали через OpenAI API. Для каждого элемента — отдельный промпт: H1, meta description, body, FAQ. Так проще контролировать длину, тон и уникальность, чем одним большим запросом на всю страницу.

Python · OpenAI API
import openai
import pandas as pd

def generate_text(prompt):
    response = openai.ChatCompletion.create(
        model="gpt-4",
        messages=[{"role": "user", "content": prompt}],
        temperature=0.7
    )
    return response["choices"][0]["message"]["content"]

df = pd.read_csv("pages.csv")

df["H1"] = df.apply(
    lambda row: generate_text(
        f"Создай H1 для билетов {row['Departure City']} – {row['Arrival City']}"
    ), axis=1
)
df["Meta Description"] = df.apply(
    lambda row: generate_text(
        f"Напиши meta description для страницы авиабилетов "
        f"{row['Departure City']} – {row['Arrival City']}"
    ), axis=1
)
df.to_csv("updated_pages.csv", index=False)

Выгрузка в JSON для загрузки в CMS

После генерации — экспорт в JSON-массив: каждая запись = одна страница, готовая к импорту в CMS.

Python · экспорт
import pandas as pd

df = pd.read_csv("updated_pages.csv")
df.to_json("pages.json", orient="records", force_ascii=False)

Как мы автоматизировали индексацию через Indexing API

Сканировали новые URL из базы и отправляли в Google Indexing API пачками — не ждали, пока бот сам доберётся до миллиона страниц.

Python · Google Indexing API
import json
import requests

with open("new_urls.json", "r") as f:
    urls = json.load(f)

API_URL = "https://indexing.googleapis.com/v3/urlNotifications:publish"
HEADERS = {
    "Content-Type": "application/json",
    "Authorization": "Bearer TOKEN"
}

def index_url(url):
    data = {"url": url, "type": "URL_UPDATED"}
    response = requests.post(API_URL, headers=HEADERS, json=data)
    return response.json()

for i in range(0, len(urls), 100):
    batch = urls[i:i+100]
    for url in batch:
        result = index_url(url)
        print(result)

Оптимизировали частоту запросов, чтобы Google не посчитал нас ботами:

  • Между запросами — пауза random.uniform(1, 3) секунды.
  • Индексацию прокидывали не всех страниц сразу, а с задержкой 3–4 дня — для естественного роста.

Верстаем продуктовую страницу: удобной и продающей

Главное — быстро дать всю нужную информацию. Вверху маршрут, даты и количество путешественников, которые можно менять. Заголовок, адрес, рейтинг — сразу видно, стоит ли бронировать. Фото крупные, листаются в один клик.

Рейтинг детализирован по категориям — локация, сервис, чистота, завтрак, номер. Удобства иконками, чек-ин и локация перед глазами. Кнопка «Забронировать» всегда на виду.

Страница бронирования отеля GLK PREMIER The Home Suites & Spa: рейтинг, удобства, фотографии номеров и информация о перелёте
Страница бронирования отеля GLK PREMIER The Home Suites & Spa: рейтинг, удобства, фотографии номеров и информация о перелёте
Рейтинг отеля GLK PREMIER The Home Suites & Spa с оценками по категориям, отзывами туристов и общей информацией о размещении
Рейтинг отеля GLK PREMIER The Home Suites & Spa с оценками по категориям, отзывами туристов и общей информацией о размещении

Авиабилеты и параметры поездки

После отеля логично показать, как до него добраться. Мы добавили авиабилеты в том же стиле, чтобы не выбивались из структуры страницы.

Рядом с заголовком — уточнение, что перелёт включён, чтобы снять лишние вопросы. Показываем конкретные рейсы: время вылета, длительность, авиакомпания. Если не подходят — можно сразу изменить.

Дальше — блок с параметрами поездки: маршрут, даты, пассажиры. Кнопка «Изменить» даёт возможность быстро поменять параметры, не выходя со страницы.

Блок выбора авиабилетов и параметров поездки: включённые рейсы, даты, количество пассажиров и условия бронирования
Блок выбора авиабилетов и параметров поездки: включённые рейсы, даты, количество пассажиров и условия бронирования

Перелинковка

Добавили перелинковку. Сначала — билеты. Человек уже выбрал отель, теперь важно, как он туда попадёт. Показываем рейсы, даём возможность поменять даты.

Дальше — достопримечательности. Если пользователь не уверен, что делать в городе, ведём его в раздел с экскурсиями.

Если отель не подошёл — показываем альтернативы. Не через блок «похожие варианты», а через аргумент: «Не понравился рейтинг? Вот другие 5-звёздочные отели».

Ссылки встроили органично, по логике пользователя. Это увеличивает глубину просмотров и снижает вероятность выхода. Google видит, что страницы связаны, передаёт им вес, поднимает в поиске.

Как мы сделали выбор номера полезным для SEO

Обычно страницы отелей устроены так: загружаются скриптом, фильтры работают на фронте, Google ничего не индексирует.

Каждый номер — отдельный блок с H2, уникальными характеристиками и ценой. Заголовки не шаблонные («Double Room»), а с уточнением: «Double 1 or 2 beds deluxe sea view». Это сразу закрывает поисковые запросы вида «Отель + вид из окна».

Разметка Schema.org/Product. В неё передаём:

  • цены и доступность, чтобы Google понимал, что данные актуальны;
  • условия отмены, которые важны для пользователей и увеличивают CTR;
  • варианты питания, чтобы поисковик считал их разными предложениями, а не дублями.

Динамическая кнопка «Показать другие номера» открывает список через серверный рендеринг. Google видит все номера и индексирует их как отдельные ссылки, а не скрытые фильтры.

Выбор номеров в отеле: варианты размещения, цены, условия бронирования и возможность гибкой отмены
Выбор номеров в отеле: варианты размещения, цены, условия бронирования и возможность гибкой отмены

Итог: каждый вариант номера — точка входа в поиске. Страницы не конкурируют друг с другом, а расширяют охват. Больше контента → выше шанс занять выдачу.

Выбор маршрута

Пользователь может менять города, даты и добавлять направления — всё в одном окне.

Но главное — SEO. Каждый новый маршрут генерирует индексируемый URL, а не скрытый параметр.

Если меняют «Амстердам → любой город», сайт создаёт /flights-from-amsterdam/, что перехватывает низкочастотный трафик.

Кнопка «Добавить направление» усиливает внутреннюю перелинковку. Google видит связанные маршруты, пользователи — больше вариантов.

Форма редактирования маршрута: выбор города отправления, назначения, дат и добавление нового направления
Форма редактирования маршрута: выбор города отправления, назначения, дат и добавление нового направления

Популярные маршруты: SEO и перелинковка

Каждый маршрут — отдельная индексируемая страница. Вместо параметров в URL генерируем /flights/milano-londra/, чтобы Google видел их как полноценные посадочные.

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

Система раз в сутки пересчитывает рейтинг маршрутов на основе:

  • Частотности запросов — API Serpstat, Google Trends, самописное решение коллег по куки;
  • Бронирований — история продаж;
  • Кликов пользователей — самописное решение коллег.

Формула ранжирования:

Score = (SearchVolume × 0.5) + (Bookings × 0.3) + (Clicks × 0.2)

Python · сортировка маршрутов
df = df.sort_values(by="score", ascending=False)
df.to_csv("popular_routes.csv", index=False)
Список популярных маршрутов: автоматически обновляемые направления с динамическими изображениями и ссылками
Список популярных маршрутов: автоматически обновляемые направления с динамическими изображениями и ссылками

Ссылки формируются в формате /flights/milano-londra/, а изображения подставляются автоматически.

Маршруты всегда актуальны, Google их индексирует, пользователи видят только востребованные направления.

Результат

Запустили 1 000 000 страниц, развернули полную SEO-структуру.

Трафик: 7,74 млн кликов, 570 млн показов за 16 месяцев. Средняя позиция 9.9, CTR 1.4%.

7.74Mкликов за 16 мес.
570Mпоказов
1.4%средний CTR
9.9средняя позиция
SEO-результаты проекта: 7,74 млн кликов, 570 млн показов, 1,4% CTR, 9.9 средняя позиция, 245K страниц в индексе из 1,1 млн
SEO-результаты проекта: 7,74 млн кликов, 570 млн показов, 1,4% CTR, 9.9 средняя позиция, 245K страниц в индексе из 1,1 млн

Изображения дали дополнительный охват: 67,4K кликов, 15,5M показов. График показывает рост после добавления уникальных фото.

Индексация: 245K страниц в Google из 1,1 млн. Остальные подтягиваем через Sitemap, внутренние ссылки и загрузку контента.

График индексации страниц: 245K страниц в индексе, 878K не проиндексированы, динамика роста за последние месяцы
График индексации страниц: 245K страниц в индексе, 878K не проиндексированы, динамика роста за последние месяцы

Миллион URL — не разовая генерация, а работающая SEO-машина: индексация, перелинковка и контент продолжают наращивать органику.

Ещё кейсы

Все кейсы
Travel

lastminute.com: 13,1 млн кликов

7 миллионов SEO-страниц через programmatic SEO в travel — UK и Европа.

B2B

ИНТЕРВОЛГА: ТОП-1 на Битрикс

+82% трафика по коммерческим запросам, +46% заявок на Bitrix24, без закупки ссылок.

E-commerce

B-ZONE: ×4 органики

Интернет-магазин игровых ПК: 5 200 запросов, 70 посадочных, ×4 трафика за 4 месяца.

Нужен programmatic SEO или масштабирование контента?

Разберём ваш проект: где теряется индексация, как собрать карту намерений и не словить фильтры. Напишите — отвечу лично.