Парсинг рекламной выдачи: объявления Яндекса и Google через API

· парсинг · реклама

Первые два-три места в выдаче по коммерческому запросу обычно куплены. Органика начинается ниже, а сверху стоят объявления — и это отдельный слой данных, который в обычном отчёте о позициях не виден вовсе. Кто там стоит, что обещает в заголовке, какие страницы продвигает быстрыми ссылками — всё это собирается тем же запросом, что и органика.

Параметр один: ads=1. Работает в /api/yandex, /api/google и /api/yandex/images и стоит 0.01 ₽ за каждую страницу, на которой реклама нашлась. Не нашлась — надбавка возвращается, и запрос обходится в обычную цену.

Зачем собирать чужую рекламу

Как это выглядит

https://jsonseo.ru/api/yandex?key=ВАШ_КЛЮЧ&text=купить+пластиковые+окна&lr=213&ads=1
https://jsonseo.ru/api/google?key=ВАШ_КЛЮЧ&q=купить+пластиковые+окна&ads=1
https://jsonseo.ru/api/yandex/images?key=ВАШ_КЛЮЧ&text=пластиковые+окна&ads=1

Рядом с results появляется массив ads. Органика при этом не меняется: объявления в неё не подмешиваются и позиций не сдвигают, поэтому отчёт о позициях от ads=1 не поедет. В картинках так же: реклама там стоит отдельным блоком над сеткой, а сама сетка остаётся органической — все двадцать картинок страницы ваши.


"ads": [
    {
        "block": "top",
        "position": 1,
        "page": 0,
        "domain": "okna-veka.ru",
        "url": "https://okna-veka.ru/plastikovye-okna/",
        "displayUrl": "okna-veka.ru/пластиковые-окна",
        "title": "Пластиковые окна от производителя — замер бесплатно",
        "description": "Окна VEKA по цене завода. Рассрочка 0%, монтаж за 1 день...",
        "label": "Реклама",
        "format": "text",
        "sitelinks": [
            {"title": "Каталог"},
            {"title": "Рассчитать цену"}
        ]
    }
]

Форма одна везде — и у обоих поисковиков, и в картинках, — так что разбор пишется один раз. Полное описание полей — в документации.

Три поля, которые важнее остальных

block и position отвечают на вопрос «где именно стояло объявление». top — над органикой, bottom — под ней, а у Яндекса бывает ещё inline: он подмешивает объявления между органическими результатами. Разница существенная — верхний блок и нижний собирают несопоставимо разное внимание.

page — страница выдачи, с которой снято объявление. Нумерация та же, что у параметра page в запросе: с нуля и абсолютная. Без этого поля первое объявление второй страницы было бы неотличимо от первого объявления первой — все страницы приезжают одним списком.

format различает обычное объявление и товар из карусели. Карусель — одно место в выдаче, но рекламодателей в ней обычно несколько: в замере на шесть карточек пришлось пять разных доменов. Поэтому она не склеивается в одну запись — иначе товары одного оказались бы приписаны другому, — а приходит отдельными объявлениями с общим номером group. Собрать ленту обратно можно по нему, а сравнить рекламодателей — по domain.

Кликовых ссылок в ответе нет

Это стоит объяснить отдельно, потому что первое, чего от парсера рекламы ждут, — ссылку, по которой объявление открывается.

В выдаче объявление ведёт не на сайт рекламодателя, а на счётчик поисковика. Переход по такому адресу засчитывается как клик, и за него платит рекламодатель — тот самый, чью рекламу вы изучаете. Робот, который обходит выдачу и дёргает такие ссылки, сжигает чужой бюджет; кто-то делает это и намеренно. Мы такими вещами не занимаемся и кликовые адреса наружу не отдаём вовсе.

В поле url приходит посадочная страница, полученная без перехода по счётчику и очищенная от кликовых меток. Когда вычислить её не удаётся, поля просто нет — выдумывать адрес или подставлять счётчик мы не будем.

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

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

Чего в ответе не будет

У Google рекламы может не быть вовсе

Это стоит знать до того, как строить на нём отчёт. Реклама Google сильно зависит от региона: есть рынки, где по коммерческому запросу не показывается ни одного объявления, каким бы конкурентным он ни был. Заметно влияет и язык выдачи: на части значений hl объявлений приходит ощутимо меньше.

Практический вывод: если нужна реклама Google, задавайте регион явно — uule или region — и убедитесь на нескольких запросах, что на этом рынке она вообще показывается. Пустой ответ в такой ситуации ничего не говорит о конкуренции по запросу, он говорит о рынке. У Яндекса этой оговорки нет.

Что учесть при регулярном сборе

Реклама подвижнее органики. Состав объявлений меняется в течение суток: аукцион живой, бюджеты кончаются к вечеру и обновляются ночью. Один замер говорит о моменте, а не о неделе; если нужен вывод про конкурента — собирайте по расписанию и в одно и то же время.

Реклама сильнее зависит от региона. Кампании настраивают по городам, и по одному запросу в Москве и Екатеринбурге может не совпасть ни один рекламодатель. Собирать без указания региона — значит получить выдачу неизвестно для кого; про региональные параметры есть отдельная статья про проверку позиций по регионам.

Запрос идёт дольше. И заметнее всего у Google; с ростом pages задержка накапливается. Если собираете рекламу пачками, поднимите таймауты и не ставьте ads=1 там, где нужна только органика, — заодно и не переплатите.

Платите только за страницы с рекламой. Надбавка резервируется на все запрошенные страницы вперёд, а после ответа лишнее возвращается: pages=5&ads=1 спишет 0.10 ₽, и если объявления найдутся на двух страницах, вернётся 0.03 ₽. Запрос по теме, где рекламы нет вовсе, обойдётся в обычную цену.

Пустой массив — это ответ. ads: [] означает «рекламу просили, объявлений на этой странице не было» — полноценный факт, а не сбой. Отсутствие поля значит другое: что ads=1 не передавали. Один пустой ответ, впрочем, говорит только про этот запрос и этот момент: аукцион живой, и вывод «по запросу не рекламируются» делается по серии замеров, а не по одному.

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


Читайте дальше

Страны и языки в Google: параметры gl и hl

Москва в uule и gl=by дают белорусскую выдачу, а незнакомый hl Google молча превращает в английский. Разбираем, кто за что отвечает, и даём полные списки — те же, по которым API проверяет запросы.

Страны, рынки и языки в Bing: mkt, cc и setlang

Можно запросить Катар и получить московскую выдачу. Разбираем, кто из трёх параметров за что отвечает, и даём полные списки — те же, по которым API проверяет запросы.