В этой статье мы разберем, как выгрузить данные из Google Ads по API пошагово.
API позволяет автоматизировать и глубоко анализировать рекламные данные, выходя за рамки стандартных отчетов. Это решает следующие задачи:
- Автоматизация отчётности: Регулярная (по расписанию) выгрузка данных в нужные источники (BI-системы, дашборды, базы данных) для создания актуальных и детализированных отчетов без ручного труда.
- Глубокая кастомизация аналитики: Доступ к самым гранулярным данным и полям, недоступным через стандартный интерфейс. Позволяет создавать любые кастомные метрики и сложные фильтры для уникальных аналитических задач.
- Построение собственного Data Warehouse: Накопление исторически точных данных в собственных хранилищах (BigQuery, PostgreSQL) для долгосрочной аналитики, предиктивного моделирования и сквозной аналитики с данными из других источников.
- Интеграция с внешними системами: Автоматическая передача рекламных данных (расходы, клики, конверсии) в CRM, внутренние BI-платформы, финансовые и другие бизнес-системы.
- Массовые операции и управление аккаунтами: Программное управление рекламными кампаниями (создание, изменение, удаление объявлений, ключевых слов) в больших объемах, автоматизация стратегий и оптимизации.
Для выгрузки я буду использовать программу PyCharm, язык программирования Python, библиотеку Google Ads API Client Library for Python, язык GAQL для запросов, документацию Google ADS API.
Готовый репозиторий на GitHab – https://github.com/kontekstsas/google-ads-scripts
В дополнение к текстовому материалу я подготовила полный видео-разбор настроек описанных здесь. Посмотреть можно на YouTube:
Настройка будет проводится поэтапно:
- Настройка аккаунта Google Ads и получения токена разработчика (стандартный доступ);
- Настройка проекта в Google Cloud Platform (GCP) и активация API;
- Создание учетных данных OAuth 2.0 (получение Client ID и Client Secret);
- Получение ID клиента (Customer ID);
- Настройка проекта в PyCharm;
- Установка Google Cloud Cli;
- Установка библиотек;
- Получение Refresh Token;
- Настройка файла конфигурации googleads.yaml;
- Написание Python-кода для выгрузки отчета;
- Запуск программы в PyCharm.
1. Настройка аккаунта Google Ads и получения токена разработчика
Первое – вам понадобится управляющий аккаунт Google Ads (MCC), только в нем можно получить доступ к API. Необходимо заполнить специальную форму и отправить заявку на доступ.
Пример заполнения формы:
Важно! Когда вы в первый раз заполните форму – вы получите тестовый доступ к API сразу, но нам нужен стандартный доступ. Для этого на этой же странице после получения тестового токена, нужно нажать Подать заявку на базовый доступ.
И на открывшейся странице заполнить форму на английском языке. Я не буду пошагово объяснять, что там за поля. Вы можете перевести в браузере. Единственную вещь которую я обозначу это п.7 – Здесь нужно прикрепить документацию о вашем приложении в формате .pdf, .doc или .rtf. Вот пример, который дает Google.
Здесь все относительно понятно, вы можете перевести и написать ее наподобие примера, но не забудьте удалить пример интерфейса (если у вас его нет).
Вот пример моей документации, она заполняется также на английском языке:
После того, как вы заполнили форму и подали заявку. Нужно подождать несколько дней когда ее рассмотрят. У меня это заняло около 7 дней. Затем, вы получите уведомление на указанную почту. А в интерфейсе доступ сменится на Стандартный.
На этом с этапом получения токена закончено, он нам понадобится позже.
2. Настройка проекта в Google Cloud Platform (GCP) и активация API
Следующим этапом нам необходимо создать проект в Google Cloud Platform. Я не буду объяснять в этой статье, как там зарегистрироваться. В интернете есть множество статей, пример одна из них https://teletype.in/@delarcloud/how-to-reg-googlecloud.
Единственное, что хотела бы сказать, если вы из РБ или РФ. Выбирайте страну US и пишите любой адрес из US (можно погуглить). Так как РБ вообще нет в списке. Я сделала страну US и адрес, но привязала свою карту VISA (на счет РФ не знаю, возможно карты не пройдут). Моя белорусская прошла. P.S. привязка карты нам нужна, чтобы использовать все возможности, не факт, что вам придется что-то платить. Мой расход в мес 0,01$ оттуда за несколько проектов с разными задачами.
После того, как мы создали аккаунт там – необходимо создать новый проект. Это можно сделать с помощью кнопки New Project.
Даем название проекту и выбираем организацию (если есть). Нажимаем Create.
После создания вы увидите уведомление, можно сразу перейти в проект. Либо сверху по кнопке вы можете увидеть, в каком проекте вы находитесь.
Далее через меню слева нам необходимо перейти в APIs & Services – Enabled APIs & services
Здесь ищем Google ADS API прямо в поисковой строке сверху. Переходим по первой ссылке.
В открывшемся окне нажимаем кнопку Enable (включить)
Также сразу мы создадим проект в самом Google BigQuery и датасет для выгрузки данных. Для этого перейдем в BigQuery Studio:
Рядом с названием проекта нажмем 3 точки и кнопку Create dataset
Назовем его, регион – можно оставить Multi-region
На этом все, датасет нам понадобится для того, чтобы в него загружать таблицы из API.
3. Создание учетных данных OAuth 2.0 (получение Client ID и Client Secret)
Этот шаг мы будем выполнять также в Google Cloud Console. Для этого переходим в APIs & Services – Credentials
Далее нажимаем Create credentials – OAuth client ID
Настроим consent screen
Заполним информацию о приложении : название приложения, емейл
Настройки доступа, скорее всего Internal будет недоступен, поэтому выбираем вариант 2.
Email снова, и согласие.
После этого обязательно в Audience добавляем email тестового пользователя (можно свой)
В Overview создаем нового клиента
Для него выбираем Desktop App и даем любое название
После создания вы увидите Client ID и Client Secret – они нам и нужны! Сохраните их себе куда-нибудь. Также в любой момент вы сможете их найти на той же вкладке, провалившись в вашего созданного клиента.
4. Получение ID клиента (Customer ID)
Это самый простой шаг, здесь вам нужен просто ID вашего аккаунта Google Ads, который вы можете найти в интерфейсе (важно! без пробелов и тире)
5. Настройка проекта в PyCharm и скачивание Python
PyCHarm – это это интегрированная среда разработки (IDE) для языка программирования Python. Ее можно скачать здесь.
Python на ПК можно загрузить из поиска. Например по ссылке. С установкой я думаю понятно будет. Разбирать тут не будем.
После запуска программы PyCharm мы создаем новый проект.
В итоге мы получим примерно такую структуру, в которой мы и будем работать в дальнейшем
В корневом файле мы создадим новую директорию и назовем ее srс, а в ней и еще две директории, в которую будут храниться наши скрипты, (например, ga_api_scripts) и creds (директория с доступами).
6. Установка Google Cloud Cli
Вам нужно один раз настроить на вашем компьютере учетные данные по умолчанию (Application Default Credentials), чтобы любые скрипты могли автоматически получать доступ к вашим сервисам Google Cloud, таким как BigQuery. Это делается с помощью инструмента Google Cloud CLI.
Устанавливается довольно просто на ПК, после у вас будет создан клиент на рабочем столе.
7. Установка библиотек
Следующим этапом мы установим библиотеки для работы, для этого мы создадим в корневом каталоге файл requirements.txt, в котором просто пропишем:
google-ads google-cloud-bigquery pandas google-auth-oauthlib
Пример:
Для установки библиотек выполним в терминале pip install -r requirements.txt
Для Google Cloud Cli в терминале PyCharm выполним gcloud auth application-default login
После ввода команды в вашем браузере автоматически откроется страница входа Google.
- Войдите в тот же Google-аккаунт, у которого есть доступ к вашему проекту в Google Cloud.
- Разрешите приложению доступ к вашим данным.
- После этого gcloud сохранит специальный файл с учетными данными на вашем компьютере.
Дополнительно установим библиотеку:
python -m pip install pandas-gbq
8. Получение Refresh Token
Последний шаг для получения доступов – это получение refresh_token. Для его получения мы создадим отдельный скрипт в нашей папке ga_api_scripts, который назовем generate_refresh_token.py
В нем необходимо добавить 2 переменные (мы их получили на этапе выше):
DEFAULT_CLIENT_ID = 'YOUR_CLIENT_ID'
DEFAULT_CLIENT_SECRET = 'YOUR_CLIENT_SECRET'
#!/usr/bin/env python
#
# Copyright 2014 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Generates refresh token for AdWords using the Installed Application flow."""
import argparse
import sys
from google_auth_oauthlib.flow import InstalledAppFlow
from oauthlib.oauth2.rfc6749.errors import InvalidGrantError
# Your OAuth2 Client ID and Secret. If you do not have an ID and Secret yet,
# please go to https://console.developers.google.com and create a set.
DEFAULT_CLIENT_ID = 'YOUR_CLIENT_ID'
DEFAULT_CLIENT_SECRET = 'YOUR_CLIENT_SECRET'
# The AdWords API OAuth2 scope.
SCOPE = u'https://www.googleapis.com/auth/adwords'
# The redirect URI set for the given Client ID. The redirect URI for Client ID
# generated for an installed application will always have this value.
_REDIRECT_URI = 'urn:ietf:wg:oauth:2.0:oob'
parser = argparse.ArgumentParser(description='Generates a refresh token with '
'the provided credentials.')
parser.add_argument('--client_id', default=DEFAULT_CLIENT_ID,
help='Client Id retrieved from the Developer\'s Console.')
parser.add_argument('--client_secret', default=DEFAULT_CLIENT_SECRET,
help='Client Secret retrieved from the Developer\'s '
'Console.')
parser.add_argument('--additional_scopes', default=None,
help='Additional scopes to apply when generating the '
'refresh token. Each scope should be separated by a comma.')
class ClientConfigBuilder(object):
"""Helper class used to build a client config dict used in the OAuth 2.0 flow."""
_DEFAULT_AUTH_URI = 'https://accounts.google.com/o/oauth2/auth'
_DEFAULT_TOKEN_URI = 'https://accounts.google.com/o/oauth2/token'
CLIENT_TYPE_WEB = 'web'
CLIENT_TYPE_INSTALLED_APP = 'installed'
def __init__(self, client_type=None, client_id=None, client_secret=None,
auth_uri=_DEFAULT_AUTH_URI, token_uri=_DEFAULT_TOKEN_URI):
self.client_type = client_type
self.client_id = client_id
self.client_secret = client_secret
self.auth_uri = auth_uri
self.token_uri = token_uri
def Build(self):
"""Builds a client config dictionary used in the OAuth 2.0 flow."""
if all((self.client_type, self.client_id, self.client_secret,
self.auth_uri, self.token_uri)):
client_config = {
self.client_type: {
'client_id': self.client_id,
'client_secret': self.client_secret,
'auth_uri': self.auth_uri,
'token_uri': self.token_uri
}
}
else:
raise ValueError('Required field is missing.')
return client_config
def main(client_id, client_secret, scopes):
"""Retrieve and display the access and refresh token."""
client_config = ClientConfigBuilder(
client_type=ClientConfigBuilder.CLIENT_TYPE_INSTALLED_APP, client_id=client_id,
client_secret=client_secret)
flow = InstalledAppFlow.from_client_config(
client_config.Build(), scopes=scopes)
# Note that from_client_config will not produce a flow with the
# redirect_uris (if any) set in the client_config. This must be set
# separately.
flow.redirect_uri = _REDIRECT_URI
auth_url, _ = flow.authorization_url(prompt='consent')
print('Log into the Google Account you use to access your AdWords account '
'and go to the following URL: \n%s\n' % auth_url)
print('After approving the token enter the verification code (if specified).')
code = input('Code: ').strip()
try:
flow.fetch_token(code=code)
except InvalidGrantError as ex:
print('Authentication has failed: %s' % ex)
sys.exit(1)
print('Access token: %s' % flow.credentials.token)
print('Refresh token: %s' % flow.credentials.refresh_token)
if __name__ == '__main__':
args = parser.parse_args()
configured_scopes = [SCOPE]
if not (any([args.client_id, DEFAULT_CLIENT_ID]) and
any([args.client_secret, DEFAULT_CLIENT_SECRET])):
raise AttributeError('No client_id or client_secret specified.')
if args.additional_scopes:
configured_scopes.extend(args.additional_scopes.replace(' ', '').split(','))
main(args.client_id, args.client_secret, configured_scopes)
Далее мы запускаем этот скрипт, можно прямо кликнув по вкладке со скриптом.
В терминале появится такая ссылка, переходим по ней:
После вам предложат залогиниться с gmail почты и дать разрешения, а затем вы увидите такое окно, отсюда нам нужен код. Копируем его, и возвращаемся в терминал, куда вставляем код
.После этого вы получите строку с Refresh token
Копируем токен и сохраняем его себе.
9. Настройка файла конфигурации googleads.yaml
В папке creds мы создадим новый файл формата .yaml, назовем его googleads.yaml. Этот файл и есть ключ к подключению API. В дальнейшем все ваши скрипты будут использовать эти данные и проводить заново этапы сбора информации не потребуется.
В него добавим следующий код. В котором мы можем сразу заполнить ту информацию, которую мы собрали раньше: developer_token, login_customer_id, client_id, client_secret.
Сюда же добавляем refresh_token, который мы получили на предыдущем шаге.
На этом все. Файл с доступами полностью готов.
############################################################################# # Required Fields # ############################################################################# developer_token: 'YOUR DEVELOPER TOKEN' ############################################################################# # Optional Fields # ############################################################################# login_customer_id: 'YOUR CUSTOMER ID' # user_agent: INSERT_USER_AGENT_HERE # partial_failure: True validate_only: False use_proto_plus: True ############################################################################# # OAuth2 Configuration # # Below you may provide credentials for either the installed application or # # service account flows. Remove or comment the lines for the flow you're # # not using. # ############################################################################# # The following values configure the client for the installed application # flow. client_id: 'YOUR CLIENT ID' client_secret: 'YOUR CLIENT SECRET' refresh_token: 'YOUR REFRESH TOKEN' # The following values configure the client for the service account flow. # path_to_private_key_file: INSERT_PATH_TO_JSON_KEY_FILE_HERE # delegated_account: INSERT_DOMAIN_WIDE_DELEGATION_ACCOUNT ############################################################################# # ReportDownloader Headers # # Below you may specify boolean values for optional headers that will be # # applied to all requests made by the ReportDownloader utility by default. # ############################################################################# # report_downloader_headers: # skip_report_header: False # skip_column_header: False # skip_report_summary: False # use_raw_enum_values: False
10. Написание Python-кода для выгрузки отчета
Далее я приложу стандартный код по выгрузке данных кампании, но вы можете его корректировать под свои нужды. Он предполагает выгрузку данных по id кампании, названии кампании, id группы объявлений, названии группы объявлений, дате, показам, кликам, конверсиям, расходу.
При необходимости даты можно поменять в этом блоке (установив start_date_str, end_date_str). По умолчанию скрипт будет выгружать последние 90 дней.
Скрипт добавляем новым файлом в нашу папку.
from datetime import datetime, timedelta
import argparse
import sys
import pandas as pd
from google.ads.googleads.client import GoogleAdsClient
from google.ads.googleads.errors import GoogleAdsException
from google.cloud import bigquery
from google.cloud.bigquery import SchemaField # Для определения схемы BigQuery
# --- ФУНКЦИЯ 1: ПОЛУЧЕНИЕ ОСНОВНЫХ ДАННЫХ ИЗ GOOGLE ADS API ---
def get_basic_ad_performance_data(client, customer_id, start_date_str, end_date_str):
"""
Загружает базовые данные по кампаниям и группам объявлений (показы, клики, стоимость)
из Google Ads API, сегментированные по дате.
Возвращает pandas DataFrame.
"""
ga_service = client.get_service("GoogleAdsService")
print(f"\n1. Запрос базовых данных (показы, клики, стоимость) из Google Ads API за период с {start_date_str} по {end_date_str}...")
query = f"""
SELECT
campaign.id,
campaign.name,
ad_group.id,
ad_group.name,
segments.date,
metrics.impressions,
metrics.clicks,
metrics.cost_micros # Стоимость в микро-единицах
FROM
ad_group
WHERE
segments.date BETWEEN '{start_date_str}' AND '{end_date_str}'
ORDER BY
segments.date ASC, campaign.id ASC, ad_group.id ASC
"""
results_list = []
try:
stream = ga_service.search_stream(customer_id=customer_id, query=query)
for batch in stream:
for row in batch.results:
results_list.append({
"date": row.segments.date,
"campaign_id": row.campaign.id,
"campaign_name": row.campaign.name,
"ad_group_id": row.ad_group.id,
"ad_group_name": row.ad_group.name,
"impressions": row.metrics.impressions,
"clicks": row.metrics.clicks,
"cost": row.metrics.cost_micros / 1_000_000 # Переводим из микро-единиц
})
df = pd.DataFrame(results_list)
print(f"Получено {len(df)} строк данных из Google Ads.")
return df
except GoogleAdsException as ex:
print(f'Ошибка запроса Google Ads API (ID: "{ex.request_id}"): {ex.error.code().name}')
print(f"Сообщение: {ex.error.message}")
sys.exit(1)
except Exception as e:
print(f"Непредвиденная ошибка при получении данных: {e}")
sys.exit(1)
return pd.DataFrame() # Возвращаем пустой DataFrame в случае ошибки
# --- ФУНКЦИЯ 2: ЗАГРУЗКА ДАННЫХ В BIGQUERY (С АВТОСОЗДАНИЕМ ТАБЛИЦЫ) ---
def load_data_to_bigquery(df, project_id, table_id):
"""
Загружает pandas DataFrame в указанную таблицу BigQuery.
Автоматически создает таблицу, если она не существует.
"""
if df.empty:
print("Нет данных для загрузки в BigQuery.")
return
bq_client = bigquery.Client(project=project_id)
try:
dataset_id = table_id.split('.')[1]
table_name = table_id.split('.')[2]
dataset_ref = bq_client.dataset(dataset_id)
table_ref = dataset_ref.table(table_name)
except IndexError:
print(f"Ошибка: Неверный формат 'table_id'. Ожидается 'project.dataset.table'. Получено: '{table_id}'")
sys.exit(1)
print(f"\n2. Проверка и загрузка данных в таблицу BigQuery: {table_id}...")
try:
bq_client.get_table(table_ref)
print(f"Таблица '{table_id}' уже существует.")
job_config = bigquery.LoadJobConfig(write_disposition="WRITE_TRUNCATE") # Перезаписываем существующую
except Exception:
print(f"Таблица '{table_id}' не найдена. Создаем новую.")
schema = []
for col_name, dtype in df.dtypes.items():
if col_name == "date": # Специальная обработка для столбца 'date'
schema.append(SchemaField(col_name, "DATE", mode="NULLABLE"))
elif "id" in col_name.lower(): # Для ID (Campaign ID, Ad Group ID)
schema.append(SchemaField(col_name, "INTEGER", mode="NULLABLE"))
elif "int" in str(dtype):
schema.append(SchemaField(col_name, "INTEGER", mode="NULLABLE"))
elif "float" in str(dtype):
schema.append(SchemaField(col_name, "FLOAT", mode="NULLABLE"))
elif "object" in str(dtype): # pandas 'object' обычно для строк
schema.append(SchemaField(col_name, "STRING", mode="NULLABLE"))
else:
schema.append(SchemaField(col_name, "STRING", mode="NULLABLE")) # По умолчанию для неизвестных типов
table = bigquery.Table(table_ref, schema=schema)
bq_client.create_table(table)
print(f"Таблица '{table_id}' успешно создана со схемой: {[field.name + ':' + field.field_type for field in schema]}")
job_config = bigquery.LoadJobConfig(write_disposition="WRITE_TRUNCATE") # После создания также перезаписываем
try:
if 'date' in df.columns:
df['date'] = pd.to_datetime(df['date']).dt.date
job = bq_client.load_table_from_dataframe(df, table_ref, job_config=job_config)
job.result() # Дождитесь завершения задания
print(f"🎉 Данные успешно загружены в BigQuery!")
except Exception as e:
print(f"Ошибка при загрузке данных в BigQuery: {e}")
sys.exit(1)
# =====================================================================
# ОСНОВНОЙ БЛОК ЗАПУСКА ПРОГРАММЫ
# =====================================================================
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Загружает базовые данные Google Ads в Google BigQuery.")
parser.add_argument("-c", "--customer_id", type=str, required=True, help="ID клиента Google Ads (без дефисов).")
parser.add_argument("-p", "--project_id", type=str, required=True, help="ID проекта Google Cloud.")
parser.add_argument("-t", "--table_id", type=str, required=True,
help="Полный ID таблицы в BigQuery (например, 'my_project.my_dataset.my_table').")
parser.add_argument("--config_file", type=str, required=True, help="Полный путь к файлу google-ads.yaml.")
args = parser.parse_args()
print("--- Запуск выгрузки базовых данных из Google Ads API в BigQuery ---")
try:
googleads_client = GoogleAdsClient.load_from_storage(path=args.config_file, version="v18")
print("Клиент Google Ads успешно инициализирован.")
except Exception as e:
print(f"Не удалось инициализировать клиент Google Ads. Проверьте 'google-ads.yaml' и путь к нему.")
print(f"Ошибка: {e}")
sys.exit(1)
today = datetime.now()
end_date = today - timedelta(days=1)
start_date = today - timedelta(days=90)
start_date_str = start_date.strftime('%Y-%m-%d')
end_date_str = end_date.strftime('%Y-%m-%d')
print(f"Выгружаем данные за период с {start_date_str} по {end_date_str}")
performance_df = get_basic_ad_performance_data(googleads_client, args.customer_id, start_date_str, end_date_str)
if not performance_df.empty:
load_data_to_bigquery(performance_df, args.project_id, args.table_id)
else:
print("Базовые данные не получены из Google Ads, загрузка в BigQuery пропущена.")
print("\n--- Программа завершена ---")
11. Запуск программы в PyCharm
Для запуска скрипта примените команду в терминале:
python src/ga_api_scripts/download_data_test.py -c "8280615042" -p "test-proj-467516" -t "test-proj-467516.api_ga.google_ads_data" --config_file "C:/Users/ryzha/PycharmProjects/pythonProject1/src/creds/googleads.yaml"
где -c “ID аккаунта клиента”, -p “ID проекта в Bigquery”, -t “ID датасета биквери + название таблицы, которую надо создать” , –config_file “путь к файлу googleads.yaml”
После запуска вы увидите что-то примерно такое:
А затем можете зайти в проект в BigQuery и убедиться, что была создана новая таблица и в ней есть все данные.









































Добрый. А почему рефреш токены может отвалиться? за месяца 1.5 приходилось его обновлять в ручную
Здравствуйте, да сама столкнулась с этой проблемой. Токен в режиме тестирования живет всего 7 дней, Google просит публиковать приложение и в данном случае подтверждать его. Что весьма длительный процесс.
Решила тем, что перешла от использования OAuth к сервисному аккаунту