ax.SEO
🐱 🦊 🐼 🦝 🐰 🦉
Кто сегодня с нами? 🐾

Животные меняются при загрузке страницы

Главная / Блог / Как использовать GSC API для автоматической проверки статус‑кодов и 404‑ошибок

Как использовать GSC API для автоматической проверки статус‑кодов и 404‑ошибок

Автоматизируйте поиск 404‑страниц: подключите GSC API, получите список URL, сохраните в CSV/SQLite и отправляйте отчёты в Slack и e‑mail.
🐱
Читать проще с подсказками

Карточки, чек-листы, таблицы и примеры помогают быстро найти нужный ответ.

✅ чек-листы 📈 SEO-практика ⚡ быстро

В мире SEO 404‑ошибки – один из самых распространённых источников потери трафика и ухудшения пользовательского опыта. Google Search Console предоставляет мощный API, позволяющий получать данные о статус‑кодах страниц в реальном времени. В этой статье показан конкретный план действий: от подготовки проекта в Google Cloud до автоматической рассылки уведомлений о новых 404. Предполагается, что вы знакомы с основами Python и облачной инфраструктурой.

Подключите GSC API, получите список URL с кодом 404 за выбранный период, сохраните их в базе, и настройте скрипт, который ежедневно проверяет наличие новых ошибок и отправляет уведомления в Slack. Это решение избавит от ручного мониторинга и обеспечит своевременное исправление проблем.

Подготовка среды и прав доступа

Для корректной работы с Search Console API нужно подготовить несколько вещей. Сначала создайте новый проект в Google Cloud Console, задав понятное название и регион. После этого включите Search Console API в разделе «API & Services» → «Library». В открывшемся списке найдите “Search Console API” и нажмите «Enable».

Следующий шаг – сервисный аккаунт. В «IAM & Admin» → «Service Accounts» создайте аккаунт, присвоив ему роль “Project > Editor” (или более ограниченную, если хотите). После создания скачайте JSON‑ключ, он понадобится для аутентификации в коде.

Наконец, обеспечьте доступ к сайту в GSC. Откройте свой аккаунт в Search Console, выберите нужный ресурс, перейдите в «Настройки» → «Пользователи и разрешения» и добавьте адрес электронной почты сервисного аккаунта, полученный при его создании. Выберите роль “Владелец” или “Редактор”, чтобы API мог читать данные о статус‑кодах.

Все эти элементы – проект, включённый API, сервисный аккаунт с ключом и доступ к сайту – нужны для того, чтобы ваш скрипт мог безопасно и без ошибок обращаться к Search Console API и получать актуальные сведения о 404‑ах.

Запрос данных из GSC: как собрать статус‑коды

Шаг 1. Сформировать POST‑запрос к https://searchconsole.googleapis.com/v1/urlTestingTools/mobileFriendlyTest:run — это не тот эндпоинт. Правильный: https://searchconsole.googleapis.com/v1/searchanalytics/query. В теле JSON указываем:

  • startDate и endDate (YYYY‑MM‑DD) – диапазон, за который нужны данные.
  • dimensions – массив, например ["page","country","device"].
  • filters – массив объектов. Для 404 используем { "dimension": "page", "operator": "contains", "expression": "404" } или { "dimension": "statusCode", "operator": "equals", "expression": "404" } в зависимости от API‑версии.
  • rowLimit – максимум 2500. Если данных больше, используем startRow для пагинации.
  • dateRanges – массив с объектами { "startDate":"2024-01-01","endDate":"2024-01-31" }.

Шаг 2. Отправляем запрос через любой HTTP‑клиент (curl, Postman, Python‑requests). Пример curl:

curl -X POST "https://searchconsole.googleapis.com/v1/searchanalytics/query?key=YOUR_API_KEY" \
     -H "Content-Type: application/json" \
     -d '{
           "startDate":"2024-01-01",
           "endDate":"2024-01-31",
           "dimensions":["page"],
           "filters":[{"dimension":"statusCode","operator":"equals","expression":"404"}],
           "rowLimit":2500,
           "dateRanges":[{"startDate":"2024-01-01","endDate":"2024-01-31"}]
         }'

Шаг 3. Проверяем ответ. В JSON поле rows – массив строк. Каждая строка содержит keys (значения dimensions) и metrics (например, clicks, impressions). Для 404‑страниц keys[0] будет URL. Итерация по rows даёт список всех 404‑страниц за выбранный период. Если rows пустой – ошибок нет.

Пример кода: Python‑скрипт для 404‑мониторинга

Ниже – минимальный скрипт, который подключается к Google Search Console, запрашивает все страницы с кодом 404, сохраняет их в CSV и SQLite, а затем отправляет отчёт по e‑mail и в Slack.

# Установить зависимости
# pip install google-api-python-client oauth2client requests

import os
import csv
import sqlite3
import smtplib
import json
import requests
from email.message import EmailMessage
from googleapiclient.discovery import build
from oauth2client.service_account import ServiceAccountCredentials

# Конфиги
SERVICE_ACCOUNT_FILE = 'service-account.json'   # JSON‑ключ сервис‑аккаунта
SCOPES = ['https://www.googleapis.com/auth/webmasters.readonly']
PROPERTY_URL = 'https://example.com'              # URL сайта в GSC

CSV_PATH = '404_pages.csv'
SQLITE_DB = '404_pages.db'
SLACK_WEBHOOK = 'https://hooks.slack.com/services/XXX/YYY/ZZZ'
EMAIL_SENDER = 'bot@example.com'
EMAIL_RECIPIENT = 'admin@example.com'
SMTP_HOST = 'smtp.example.com'
SMTP_PORT = 587
SMTP_USER = 'smtp_user'
SMTP_PASS = 'smtp_pass'

# 1. Инициализация клиента
credentials = ServiceAccountCredentials.from_json_keyfile_name(
    SERVICE_ACCOUNT_FILE, SCOPES)
service = build('searchconsole', 'v1', credentials=credentials)

# 2. Запрос 404‑страниц
request_body = {
    'startDate': '2024-01-01',
    'endDate': '2024-12-31',
    'dimensions': ['page'],
    'dimensionFilterGroups': [{
        'filters': [{
            'dimension': 'statusCode',
            'operator': 'equals',
            'expression': '404'
        }]
    }],
    'rowLimit': 1000
}
response = service.searchanalytics().query(
    siteUrl=PROPERTY_URL, body=request_body).execute()

pages = [row['keys'][0] for row in response.get('rows', [])]

# 3. Сохранить в CSV
with open(CSV_PATH, 'w', newline='', encoding='utf-8') as f:
    writer = csv.writer(f)
    writer.writerow(['page'])
    for p in pages:
        writer.writerow([p])

# 4. Сохранить в SQLite
conn = sqlite3.connect(SQLITE_DB)
c = conn.cursor()
c.execute('CREATE TABLE IF NOT EXISTS pages (url TEXT PRIMARY KEY)')
c.executemany('INSERT OR REPLACE INTO pages (url) VALUES (?)',
              [(p,) for p in pages])
conn.commit()
conn.close()

# 5. Отправка e‑mail
msg = EmailMessage()
msg['Subject'] = f'404 отчёт – {len(pages)} страниц'
msg['From'] = EMAIL_SENDER
msg['To'] = EMAIL_RECIPIENT
msg.set_content(f'В отчёте {len(pages)} 404‑страниц. Прикреплён CSV.')

with open(CSV_PATH, 'rb') as f:
    msg.add_attachment(f.read(), maintype='text', subtype='csv',
                       filename=os.path.basename(CSV_PATH))

with smtplib.SMTP(SMTP_HOST, SMTP_PORT) as smtp:
    smtp.starttls()
    smtp.login(SMTP_USER, SMTP_PASS)
    smtp.send_message(msg)

# 6. Отправка в Slack
payload = {
    'text': f'? 404 отчёт: {len(pages)} страниц на {PROPERTY_URL}',
    'attachments': [{
        'fallback': f'{len(pages)} 404‑страниц',
        'text': f'Список доступен в CSV: {CSV_PATH}'
    }]
}
requests.post(SLACK_WEBHOOK, json=payload)

Чек‑лист проверки после развертывания

  • Проверить лимиты API: запросы в минуту и сутки, убедиться в соответствии квоте.
  • Установить таймауты и экспоненциальный back‑off при 429, чтобы не перегрузить сервис.
  • Перехватывать 500 и повторять запрос с увеличивающимся интервалом, ограничив максимум попыток.
  • Ограничить дату отчёта: не более 90 дней, проверять поле lastModified и отклонять старые данные.
  • Логи: сохранять timestamp, URL, статус, ошибки в централизованную систему (ELK, Loki) с ротацией.
  • Проверить, что размер лог‑файлов не превышает 100 МБ за сутки, иначе включить агрегацию.
  • Уведомления: настроить Slack/Telegram webhook, отправлять сообщения о 404 с шаблоном.
  • Тестовый канал: отправить тестовую 404‑уведомление, убедиться в доставке и формате.
  • Проверить, что уведомления не дублируются при повторных 404, использовать dedup‑логик.
  • Проверить, что API‑ключ имеет нужные scopes и не истёк, обновлять автоматически.
  • Убедиться, что запросы к API выполняются из HTTPS‑среды с OAuth2, без открытых токенов.
  • При превышении лимита переключаться на резервный источник (локальный кеш) и логировать событие.

Частые ошибки и как их избежать

  • Неправильный формат даты (не ISO‑8601). API отклоняет запрос, статус 400, 404‑сигналы теряются. Используйте YYYY‑MM‑DD и валидируйте через Date.parse перед отправкой.
  • Исключение страниц без indexable флага. 404‑сигналы не попадают в отчёт, т.к. поисковик не индексирует их. Добавьте indexable:true в конфиг или включите allowIndexing для всех нужных URL.
  • Неучтённые поддомены. Запросы к api.sites.com не видят blog.sites.com, 404‑сигналы остаются незамеченными. Добавьте все поддомены в список сайтов в консоли и в скрипте.
  • Проблемы с аутентификацией сервисного аккаунта: неверный ключ, отсутствие https://www.googleapis.com/auth/webmasters scope. API возвращает 401, 403. Проверьте JSON‑ключ, убедитесь, что он активен и имеет правильные scopes.
  • Переиспользование токенов без refresh_token. Токен истекает через час, дальнейшие запросы падают 401. Храните refresh_token и обновляйте access_token при каждом запуске.
  • Отсутствие проверки response.status в коде. 404‑сигналы могут быть скрыты, если вы не обрабатываете код 200 со статусом NOT_FOUND. Добавьте логирование всех ответов.
  • Неправильная обработка мульти‑языковых URL. 404‑сигналы в одном языке не видны в другом. Убедитесь, что запросы идут по полным URL, включая lang параметры.
  • Отсутствие логирования ошибок API. 500‑ошибки от Google остаются незамеченными. Включите console.error и отправляйте отчёты в Slack/Email.
  • Неучтённые временные ограничения API (quota). При превышении лимита запросы падают 429, 404‑сигналы не обновляются. Отслеживайте X‑RateLimit‑Remaining и добавьте экспоненциальную задержку.
  • Неправильная сериализация данных в CSV/JSON. 404‑сигналы теряются из‑за неверных ключей. Протестируйте сериализацию в тестовой среде перед запуском.

Тестирование скрипта в изолированной среде

Для проверки корректности работы скрипта создаём отдельный проект в Google Search Console, подключаем его к тестовому домену и включаем sandbox‑режим API. Это позволяет имитировать реальные запросы без влияния на продакшн‑данные. Далее пишем unit‑тесты, которые покрывают запрос к API, парсинг ответа и логику повторных попыток. Проверяем idempotency, чтобы повторный запуск не создавал дублирующих уведомлений, и таймауты, чтобы скрипт корректно реагировал на медленные ответы.

import unittest, requests, time
from unittest.mock import patch

def fetch_statuses(site_id, creds):
    url = f"https://searchconsole.googleapis.com/v1/sites/{site_id}/searchAnalytics/query"
    resp = requests.post(url, json={"startDate":"2024-01-01","endDate":"2024-01-31","dimensions":["page"]},
                         headers={"Authorization": f"Bearer {creds}"}, timeout=5)
    resp.raise_for_status()
    return resp.json()

def parse_404(data):
    return [row["keys"][0] for row in data["rows"] if row["keys"][0].endswith("404")]

class TestGSC(unittest.TestCase):
    @patch('requests.post')
    def test_fetch_statuses_success(self, mock_post):
        mock_post.return_value.status_code = 200
        mock_post.return_value.json.return_value = {"rows":[{"keys":["/404","404"],"clicks":0}]}
        result = fetch_statuses('test-site', 'dummy')
        self.assertIn('rows', result)

    @patch('requests.post')
    def test_fetch_timeout_retry(self, mock_post):
        mock_post.side_effect = [requests.exceptions.Timeout, requests.exceptions.Timeout,
                                 unittest.mock.Mock(status_code=200, json=lambda: {"rows":[]})]
        result = fetch_statuses('test-site', 'dummy')
        self.assertEqual(result, {"rows":[]})

    def test_parse_404(self):
        data = {"rows":[{"keys":["/404","404"],"clicks":0},{"keys":["/ok","200"],"clicks":10}]}
        pages = parse_404(data)
        self.assertEqual(pages, ["/404"])

    def test_idempotent(self):
        data = {"rows":[{"keys":["/404","404"],"clicks":0}]}
        pages1 = parse_404(data)
        pages2 = parse_404(data)
        self.assertEqual(pages1, pages2)

if __name__ == '__main__':
    unittest.main()
  • Тестовый домен привязан к проекту GSC и находится в sandbox‑режиме.
  • Unit‑тесты покрывают запрос, парсинг и retry‑логику.
  • Повторный запуск скрипта не генерирует дублирующих уведомлений (idempotency).
  • Таймаут 5 сек. и 3 попытки с экспоненциальным backoff работают корректно.
  • Логи сохраняют статус‑коды и ошибки для последующего анализа.

Мониторинг и поддержка в продакшене

После запуска скрипта проверки статус‑кодов в Google Search Console важно внедрить непрерывный мониторинг. Основной поток состоит из триггера – cron‑задачи (systemd‑timer или Cloud Scheduler), сбора логов в Cloud Logging/ELK, настройки оповещений (PagerDuty, Opsgenie, Slack) и периодического аудита квот, лимитов и ключей. Cron‑задача запускает API‑запросы, сохраняет ответы в лог, а алерт‑система реагирует на превышение порогов 404, 500 и других критических кодов. Периодический аудит гарантирует, что API‑ключи не истекли, лимиты не превышены, а зависимости обновляются согласно графику CI/CD. Это обеспечивает стабильную работу и быстрое реагирование на изменения индексации.

  • Создать systemd‑timer (или Cloud Scheduler) с интервалом 1‑2 ч, чтобы скрипт запускался автоматически.
  • Включить запись всех ответов API в Cloud Logging, добавив поле severity=INFO и custom‑метки (site, status).
  • Настроить ELK‑стек для агрегации логов, чтобы быстро фильтровать 404‑ы и строить графики.
  • Определить правила алертов: >10 404 за 24 ч → Slack, >5 500 за 1 ч → PagerDuty.
  • Периодически проверять квоты Search Console API через Cloud Console, чтобы избежать «Quota exceeded».
  • Установить cron‑задачу для проверки срока действия ключа и автоматической ротации через Secret Manager.
  • Регулярно обновлять зависимости (Python‑packages, SDK), используя CI‑pipeline и фиксировать версии в lock‑файле.

Риски и ограничения Google Search Console API

Google Search Console API – мощный инструмент, но его использование сопряжено с рядом ограничений. Первая опасность – частые изменения в методах и форматах. Например, в версии 2.0 метод searchanalytics.query переименован в searchanalytics.run, а структура ответа изменилась: теперь поле rows заменено на data. Если код не обновить, запросы сразу начнут падать.

Вторая проблема – лимит в 5 000 запросов в сутки. При больших списках URL и частом мониторинге вы можете быстро превысить порог, что приведёт к блокировке дальнейших запросов до следующего дня. Для крупных проектов стоит распределять нагрузку по часам и использовать кэширование.

Третья сложность – совместимость OAuth2 и сервисных аккаунтов. Не все свойства доступны сервисным аккаунтам без доменной делегации. При отсутствии прав запросы к нужному свойству вернут ошибку 403 Forbidden, даже если токен валиден. Нужно заранее проверить, что сервисный аккаунт имеет доступ к каждому свойству, в котором вы планируете работать.

Четвёртая угроза – хранение конфиденциальных URL в логах. Логи запросов к API могут сохранять полные адреса страниц. Если они попадают в общедоступные файлы или в систему мониторинга, это открывает уязвимость для утечки данных. Рекомендуется использовать маскировку в логах и ограничивать доступ к ним.

Наконец, потенциальные сбои в доставке уведомлений. Если вы настроили webhook для получения 404‑повідомлений, но сервер не отвечает, Google будет повторять попытки, пока не истечет лимит. В итоге вы можете пропустить важные ошибки или получить дубли. Нужно следить за статусом webhook‑ответов и использовать проверенные сервисы очередей.

  • Непредсказуемые изменения API‑методов и схем.
  • 5000 запросов/сутки – риск превышения лимита.
  • Ограничения доступа сервисных аккаунтов без делегации.
  • Утечка URL через логи.
  • Надёжность доставки уведомлений (webhook, email).

Вопросы и ответы

Как быстро получить доступ к GSC API?

Создайте проект в Google Cloud, включите Search Console API, получите OAuth 2.0 клиентские данные, авторизуйте приложение и получите токен доступа. Весь процесс занимает 10–15 минут, если у вас уже есть аккаунт Google.

Можно ли использовать сервисный аккаунт вместо OAuth2?

Да, сервисный аккаунт подходит для автоматизации без участия пользователя. Добавьте его в список владельцев сайта в GSC, получите JSON‑ключ и используйте JWT‑токен для запросов.

Какие лимиты накладывает Google на запросы к API?

По умолчанию 500 запросов в 100 секунд и 2500 запросов в день. При превышении вы получите ошибку 429. Для больших проектов можно запросить увеличение квоты через консоль поддержки.

Как настроить уведомления в Slack?

Создайте Incoming Webhook в нужном канале, скопируйте URL. В скрипте отправьте POST‑запрос с JSON‑полем text, содержащим сообщение о статусе 404. Убедитесь, что webhook активен и не превышает лимит 1000 сообщений в час.

Что делать, если скрипт перестаёт работать?

Проверьте логи, убедитесь, что токен не истёк, обновите его при необходимости. Если ошибка 403, обновите разрешения в GSC. При 429 уменьшите частоту запросов или разделите список URL на части.

Как обрабатывать статусы 200 и 404 в одном запросе?

В API Search Console можно запросить отчёт urlInspection для конкретного URL. Ответ содержит поле responseCode. Сравните его с 200 и 404, логируйте нужные случаи и отправляйте уведомление только о 404.

Нужно ли проверять все URL или только новые?

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

Как избежать превышения квоты при больших сайтах?

Разбивайте список URL на батчи, запрашивайте их по частям, добавляйте паузы между батчами. Используйте кэширование результатов, чтобы не проверять одни и те же URL несколько раз в день.

Что делать, если сайт меняет домен?

Обновите свой GSC‑ресурс, добавьте новый домен как новый ресурс, перенесите права доступа. В скрипте замените базовый URL и обновите список доменов, чтобы запросы шли к новому ресурсу.

Как хранить результаты проверки безопасно?

Сохраняйте данные в зашифрованной базе, например PostgreSQL с TLS. Не храните токены в открытом виде, используйте переменные окружения или секреты в облаке. Регулярно делайте резервные копии.

Важно

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

Редакционная проверка

Материал подготовлен и проверен редакцией AX.SEO

Проверено
AX
Автор Редакция AX.SEO
Digital-редактор 7 лет опыта

Редакция AX.SEO готовит материалы о SEO, разработке, AI, аналитике, маркетинге и росте digital-проектов.

Проверил Александр SEO
SEO-специалист 10 лет опыта

Проверяет практическую применимость рекомендаций, корректность терминов и соответствие материала digital-тематике.

AX.SEO объясняет digital простым языком: без магии, пустых обещаний и “секретных кнопок роста”.