Любой SEO специалист знает, какая боль собирать семантику для Гугла. Одно дело, когда запросы можно пересчитать по пальцам, а когда они исчисляются тысячами, а не штуками? Как посмотреть количество запросов в Гугл по ключевым словам? Честно говоря, когда речь заходит о десятках тысяч ключевых слов, становится не по себе — голова идёт кругом, руки тянутся к старым привычным инструментам, а реальность бросает вызов. Так уж устроен сегодняшний Google Ads: привычная связка Key Collector + Google Ads + несколько прокси больше не спасает. Наступает новая эпоха, где без прямого обращения к официальному API всё становится мрачно и сложно.

Но нет худа без добра. Если вы готовы заморочиться с кодом, танцами с бубном и слегка поиграть в бюрократию с Google, то вы, скорее всего, получите прямой доступ к сокровищнице данных в виде Keyword Planner API. А это – золотая жила для любого SEO-шника, все же хотят чтобы наконец появился Гугл Вордстат, правда?. В этой статье я покажу пошаговую инструкцию, как от адского поиска сервисов с непомерными ценами (от 300 баксов в месяц?!) перейти к созданию своего собственного инструмента на базе Google Ads API. Поехали!

И да, аналога вордстата Гугла не существует, это все сказки у костра для джунов)) Сюда можно с натяжкой приплести планировщик ключевых слов Google, они в чем то похожи, но они такие разные…


Google парсер, или зачем вообще нужен доступ к планировщику ключевых слов google

Давайте посмотрим на ситуацию шире. Когда вы хотите собрать семантическое ядро в Google, вам нужны приличные массивы запросов (ну не 20 же штук!). Раньше спасал Key Collector, который уже, увы, не так хорош. Более того, российские аккаунты Гугла сейчас сильно ограничены, и в сложившейся ситуации всё упирается в дорогие аналоги типа Keyword Tool. Эти сервисы, к сожалению, жаждут денег (по сравнению с Кей Коллектором очень даже немало денег) и при этом особо ничем не выделяются — просто делают то же, что и Google Ads, только через свой интерфейс и API. А хочется ведь работать напрямую, да ещё и иметь возможность автоматизировать процесс под себя.

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

Keyword Tool сам по себе требует приличной оплаты,  есть еще Ubersuggest, по моему мнению он является урезанной копией Keyword Tool, урезанная, потому что там нет  API. 

Итог: если жаждете официального решения с возможностью запрограммировать логику так, как удобно именно вам, нужно обратиться к Google Ads API — и лучше делать это самостоятельно, без посредников в виде сервисов с ценником в 300-1000 долларов в месяц.


Парсер Гугл через АПИ, где всё начинается: токен разработчика и рекламный аккаунт

Собрать 40+ тысяч ключей? Можно попробовать! Но сперва нужна формальная часть. Да, некоторые шаги будут звучать несколько канцелярски, но если их как следует пройти, вы будете вознаграждены базой запросов, о которой раньше могли только мечтать.

  1. Вам нужен рекламный аккаунт Google Ads. Причём не пустой, а с хоть каким-то открученным бюджетом на рекламу. Без реальных трат Планировщик ключевых слов недоступен. Находите способ завести рабочий аккаунт — об этом не будем долго рассуждать, всё-таки мы тут не про контекстную рекламу почитать собрались.

  2. Создаём управляющий аккаунт. Переходим на страницу Manager Accounts (MCC) и регистрируем управляющий аккаунт. После создания — велкам в настройки: в левом сайдбаре ищем «Центр API» и находим Developer token (токен разработчика) и записываем его себе.


Google Cloud Console: Client ID, Client Secret - парсинг поисковой выдачи без этих данных невозможен

Двигаемся дальше. Надо ведь как-то авторизоваться в Google Ads API с помощью OAuth. Это требует регистрации приложения в Google Cloud Console.

  1. Авторизуемся в Google Cloud Console под тем же Google-аккаунтом, который управляет рекламным кабинетом.

  2. Создаём проект (назовите как хотите).

  3. Заходим в меню слева: APIs & Services → Library.

  4. В строке поиска ищем Google Ads API и жмём «Enable» (или «Включить»).

  5. Потом открываем APIs & Services → Credentials (Учетные данные).

  6. Нажимаем «Create Credentials» → «OAuth client ID».

  7. Тип приложения выбираем Web application.

  8. Придумываем название (пусть будет my-ads-api или что угодно).

  9. В разделе Authorized redirect URIs добавляем:

http://localhost:8081/
http://localhost:8081

10. Жмём «Create». Вы получаете два долгожданных значения: Client ID и Client Secret.

По поводу двух практически одинаковых redirect URIs, я с самого начала перепробовал несколько вариантов, и методом научного тыка было определено, что вариант со / сработал, а вариант без него оставил а всякий случай, мало ли у меня сработало со слэшем, а у кого-то наоборот, без слэша заработает

Получение refresh_token для Google Ads, чтобы собрать рабочий парсер Гугл

Чтобы ваш код мог автоматически обращаться к Google Ads, ему нужен refresh_token — долгосрочный ключ, который позволяет обновлять сессионный токен без повторного ручного логина.

Давайте получим этот токен (его, кстати, я получал дольше всего, не считая разрешение от Гугла, но об этом дальше).

Устанавливаем библиотеку для Python:

pip install google-ads

Создаём .py-файл (назовите его, например, get_refresh_token.py) и вставляем следующий код:

import logging
from google.auth.transport.requests import Request
from google_auth_oauthlib.flow import InstalledAppFlow

logging.basicConfig(level=logging.DEBUG)

def generate_refresh_token(client_id, client_secret):
    scopes = ["https://www.googleapis.com/auth/adwords"]

    flow = InstalledAppFlow.from_client_config(
        {
            "installed": {
                "client_id": client_id,
                "client_secret": client_secret,
                "auth_uri": "https://accounts.google.com/o/oauth2/auth",
                "token_uri": "https://oauth2.googleapis.com/token",
                "redirect_uris": ["http://localhost:8081/"]  # Добавляем слэш в конце
            }
        },
        scopes,
    )

    auth_url, state = flow.authorization_url(
        access_type="offline",
        include_granted_scopes="true",
        prompt='consent'
    )
    print(f"URL для авторизации: {auth_url}")

    credentials = flow.run_local_server(port=8081, state=state)
    print(f"Ваш Refresh Token: {credentials.refresh_token}")

generate_refresh_token(
    "Client ID",
    "Client secret"
)

Не забудьте в самом низу подставить свои Client ID и Client Secret из Google Cloud Console.

Запускаем:

python get_refresh_token.py

В консоли появится ссылка для авторизации в Google — открываем в браузере (ссылка должна открыться самостоятельно, но если этого не произошло сделайте это вручную), выбираем свой рекламный аккаунт. По завершении в консоли Python вы увидите итоговый refresh_token. Копируем и сохраняем его себе.


Конфигурационный файл google-ads.yaml - основа работоспособного парсера Google 

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

Создаём или редактируем файл google-ads.yaml:

developer_token: "ВАШ_ТОКЕН_РАЗРАБОТЧИКА"
client_id: "ВАШ_CLIENT_ID"
client_secret: "ВАШ_CLIENT_SECRET"
refresh_token: "ВАШ_REFRESH_TOKEN"
login_customer_id: "ВАШ_МЕНЕДЖЕРСКИЙ_ID"  # ID рекламного аккаунта

Обратите внимание: login_customer_id — это всё же ID вашего рекламного аккаунта, где крутится реклама, а не ID управляющего MCC. Не перепутайте!

Я не пробовал использовать ID менеджерского (управляющего) аккаунта, если будете использовать его номер, то и в основном скрипте должен стоять этот же ID (и не забудьте, что он должен быть без тире, просто сплошные цифры).

Повышение уровня доступа (иначе ваш парсер Google останется проектом на бумаге)

А теперь главный нюанс: даже получив всё вышеописанное, вы столкнетесь с ограничениями уровня доступа (Test Access). Чтобы API отдавал вам данные по ключевым фразам, нужно повысить уровень до базового (Basic Access). Для этого:

  1. Снова идём в Центр API вашего управляющего аккаунта (MCC).

  2. Видим, что стоит Test Access. Нажимаем на этот статус — появится «Подать заявку на базовый доступ».

  3. Заполняем форму, объясняем, что используем API для собственного рекламного анализа (или для внутреннего автоматизированного сбора семантики).

  4. Ждём одобрения (до 3 дней).

Если Google посчитает это валидным запросом, вы получите доступ. В большинстве случаев всё проходит гладко.

И еще одно важное замечание (в документации у Гугла оно указано) - ваш управляющий аккаунт должен быть связан с вашим рекламным аккаунтом. В левом меню выбираете кнопку “Аккаунты” и если вашего рекламного аккаунта там нет - жмете добавить, вставляете в пустое поле номер аккаунта, который хотим добавить и отправляете запрос. Далее на почту приходит уведомление, принимаете запрос на добавление и на этом все.


Наконец-то сбор семантики: Python-скрипт для парсинга Гугл

Ниже — код, который позволит вам собрать данные через официальное API Google Ads Keyword Planner. Буду краток: скрипт читает список ключевых фраз из CSV, затем батчами (по 10 шт.) отправляет запросы к API, получает статистику поискового трафика (среднемесячный охват, конкуренцию, вилку ставок), а потом сохраняет это всё в CSV-файл. Код выглядит так:

import csv
import time
from google.ads.googleads.client import GoogleAdsClient

def chunk_list(lst, n):
    for i in range(0, len(lst), n):
        yield lst[i:i+n]

def main():
    # Загрузка клиента из конфигурационного файла
    client = GoogleAdsClient.load_from_storage("google-ads.yaml")
    
    # Сервис для получения идей по ключевым словам
    keyword_plan_idea_service = client.get_service("KeywordPlanIdeaService")
    
    # Подставьте ваш Customer ID (без тире, например '1234567890')
    customer_id = "ВАШ_CUSTOMER_ID"
    
    # Читаем ключевики из CSV
    keywords = []
    with open("keywords.csv", "r", encoding="utf-8") as f:
        reader = csv.DictReader(f)
        for row in reader:
            kw = row['keyword'].strip()
            if kw:
                keywords.append(kw)
    
    chunk_size = 10

    with open("keyword_data.csv", "w", newline="", encoding="utf-8") as outfile:
        writer = csv.writer(outfile)
        writer.writerow([
            "keyword", 
            "avg_monthly_searches", 
            "competition", 
            "low_top_of_page_bid_micros", 
            "high_top_of_page_bid_micros"
        ])
        
        for chunk in chunk_list(keywords, chunk_size):
            # Формируем запрос
            request = client.get_type("GenerateKeywordIdeasRequest")
            request.customer_id = customer_id

            # Добавляем язык и гео:
            # Франция:
            request.geo_target_constants.append("geoTargetConstants/2250")
            # Французский язык:
            request.language = "languageConstants/1010"

            # Добавляем ключевики
            request.keyword_seed.keywords.extend(chunk)

            # Отправляем запрос
            response = keyword_plan_idea_service.generate_keyword_ideas(request=request)
            
            for idea in response.results:
                text = idea.text
                metrics = idea.keyword_idea_metrics
                avg_searches = metrics.avg_monthly_searches if metrics.avg_monthly_searches else 0
                competition = metrics.competition.name if metrics.competition else "UNSPECIFIED"
                low_bid = metrics.low_top_of_page_bid_micros if metrics.low_top_of_page_bid_micros else 0
                high_bid = metrics.high_top_of_page_bid_micros if metrics.high_top_of_page_bid_micros else 0
                
                writer.writerow([
                    text,
                    avg_searches,
                    competition,
                    low_bid,
                    high_bid
                ])

            # Пауза, чтобы не упереться в лимиты
            time.sleep(1)

if __name__ == "__main__":
    main()

Как это работает

  1. Файл keywords.csv должен содержать столбец keyword, в котором лежат ваши входные запросы (Заголовок keyword должен присутствовать обязательно).

  2. Скрипт читает CSV, режет ключи по 10 штук (чтобы не превышать лимиты API).

  3. Для каждой «порции» ключевых фраз формируется GenerateKeywordIdeasRequest.

  4. Указываются geoTargetConstants (2250 — это Франция, вы можете подставить нужный вам вариант) и languageConstants (1010 — французский язык, также можете подставить свой вариант). Настраивайте под себя, если нужно другую страну и язык.(Для поиска нужной страны или конкретного региона используйте файл с этой страницы - https://developers.google.com/google-ads/api/data/geotargets), про язык расскажу ниже.

  5. Полученные идеи по ключевым словам (которые, кстати, могут включать синонимы или расширенные формулировки) складываются в keyword_data.csv с показателями (поисковый трафик, конкуренция и т.д.).

  6. time.sleep(1) — это пауза в 1 секунду между запросами. Без пауз при очень большом объёме запросов есть риск «достучаться» до лимитов Google.

Теперь пара уточнений насчет получения языка и лимитов Гугл на разных аккаунтах, начнем с языка:

Найти в свободном доступе коды языков в числовом выражении я не смог (если поделитесь ссылкой в комментариях, буду рад), поэтому вот скрипт, который получает эти данные у Гугла через АПИ (но тут без базового аккаунта тоже не обойтись).

from google.ads.googleads.client import GoogleAdsClient

def main():
    # Загружаем клиента из конфигурационного файла
    client = GoogleAdsClient.load_from_storage("google-ads.yaml")

    # Сервис для выполнения GAQL-запросов
    ga_service = client.get_service("GoogleAdsService")

    customer_id = "ВАШ_CUSTOMER_ID"  # Подставьте ваш Customer ID без дефисов
    query = """
    SELECT language_constant.id, language_constant.code, language_constant.name, language_constant.targetable
    FROM language_constant
    ORDER BY language_constant.id
    """

    # Выполняем потоковый запрос
    response = ga_service.search_stream(customer_id=customer_id, query=query)

    # Перебираем результаты
    for batch in response:
        for row in batch.results:
            language = row.language_constant
            print(f"ID: {language.id}, Code: {language.code}, Name: {language.name}, Targetable: {language.targetable}")

if __name__ == "__main__":
    main()

Код вставляете в файл, в той же папке где у вас находится файл google-ads.yaml, не забудьте подставить ВАШ_CUSTOMER_ID.

В результате в консоли выведутся коды языков, которые можно будет использовать в дальнейшем.

Теперь коротко о лимитах:

На базовом уровне вы получите 15000 запросов к АПИ в день (то есть в одном запросе к планировщику вы можете передать до 10 ключей и на выходе получаем 150000 ключевых слов можно будет обработать за одни сутки)

На стандартном уровне лимиты не ограничены, но чтобы получить доступ к стандартному уровню, нужно будет доказать гуглу свою преданность и незапятнанную репутацию (не превышать лимитов при запросах к АПИ и потратить больше денег на рекламу)

НАДО БОЛЬШЕ ДЕНЕГ!


Напоследок

Главная «подлянка» всей схемы — это необходимость одобрения базового доступа в Google Ads API. Никакие ключи, никакой Python-скрипт не спасут, если Google не расширит вам этот уровень. Обычно всё проходит нормально, если ваш рекламный аккаунт активен и действительно используется под рекламу. Как только получаете базовый доступ, вы готовы!

Надеюсь, статья поможет всем, кто желает строить собственные семантические сборщики, не отдавая безумные деньги внешним сервисам. Главное — соблюдайте лимиты, давайте API передышку и не забывайте про корректное оформление заявок на доступ!

Удачи в ваших экспериментах, коллеги! И пусть JSON ответов будет всегда правильным, а CPC адекватным!

Комментарии (1)


  1. Roman_Maxwell
    20.12.2024 13:23

    Отличная статья, буду пробовать внедрять