Позиції в пошуку не статичні: апдейти алгоритмів Google та Яндексу, активність конкурентів, зміни на сайті — все це впливає на ранжування. Дізнаватися про зміни через тиждень-два — значить реагувати пізно. Ми налаштовуємо автоматичний моніторинг, який дає сигнал протягом 24 годин. Наша практика включає автоматизацію відстеження для 50+ проєктів, що дозволяє гарантувати надійність та точність.
Чому ручний моніторинг неефективний?
Ручна перевірка позицій — трудомісткий процес, який дає лише миттєвий зріз. Для щоденного контролю потрібно мінімум 30 хвилин на 100 ключів. Автоматизація ж працює без участі людини та фіксує навіть короткочасні просідання, які можуть бути викликані тестовими апдейтами алгоритмів. Порівняйте: ручний збір 500 ключів займає 2.5 години на день (це 60+ годин на місяць), а автоматичний — 5 хвилин на налаштування та 0 часу на збір. Помилки при ручному введенні трапляються в 5-10% записів, система виключає їх повністю. Один із клієнтів втратив 30% трафіку через те, що не помітив падіння позицій за тиждень — автоматичні алерти запобігли б втратам.
Як ми вирішуємо проблему запізнення даних?
Використовуємо API-джерела, які повертають актуальні позиції із затримкою не більше доби. Комбінація Google Search Console (безкоштовно, історичні дані) та DataForSEO (перевірка в реальному часі) дає повну картину. Для Яндексу застосовуємо офіційний XML API, який при дотриманні квоти також безкоштовний.
Порівняння підходів до моніторингу
| Параметр | Ручна перевірка | Google Search Console | DataForSEO API | Яндекс XML API |
|---|---|---|---|---|
| Вартість | Безкоштовно (час) | Безкоштовно | Від кількох центів за запит | Безкоштовно (квота) |
| Свіжість | Миттєво | 2–3 дні | Реальний час | Реальний час |
| Обсяг перевірки | 10–50 слів/год | До 1000 запитів на день | Необмежено | Квота 1000–10000 запитів на день |
| Історія | Відсутня | 28 днів | З моменту підключення | Не зберігається |
DataForSEO виграє у Google Search Console у швидкості, а у ручної перевірки — у масштабованості. Для Яндексу використовуємо офіційний XML API, який безкоштовний при дотриманні квоти.
Порівняння частоти моніторингу
| Частота | Ручний | Автоматичний | Рекомендація |
|---|---|---|---|
| Раз на день | 2.5 години на 500 ключів | 10 хвилин на налаштування + 0 на збір | Для конкурентних ніш |
| Раз на тиждень | 30 хвилин на 100 ключів | 0 хвилин | Для стабільних запитів |
| Раз на місяць | 10 хвилин на 50 ключів | 0 хвилин | Для брендових запитів |
Автоматичний моніторинг дає виграш у часі до 30 разів при щоденній перевірці.
Що входить у налаштування моніторингу
- Інтеграція з API (DataForSEO, Google Search Console, Яндекс XML) — реєстрація, отримання ключів, проброс трафіку.
- Скрипти щоденного збору — на Python з обробкою помилок, ретраями, логуванням.
- База даних на PostgreSQL — структура для зберігання історії позицій з індексами для швидких запитів.
- Система алертів — порівняння поточних з попередніми, відправка в Telegram при перевищенні порогу.
- Документація — опис архітектури, інструкція з додавання та видалення ключів.
- Гарантія — безкоштовна підтримка протягом 30 днів після запуску, виправлення помилок за гарантією.
Як це працює: покроково
- Аналіз — збираємо всі цільові ключові слова, визначаємо регіони та мови.
- Налаштування API — підключаємо джерела даних, тестуємо запити.
- Розгортання бази — створюємо таблиці
tracked_keywordsтаposition_history. - Реалізація скрипта збору — щоденний запуск за розкладом (cron або Airflow).
- Інтеграція алертів — налаштовуємо Telegram-бота, задаємо пороги.
- Запуск та моніторинг — перевіряємо коректність, даємо доступ до дашборду.
Замовте налаштування моніторингу прямо зараз, щоб не пропустити зміни позицій.
Приклад інтеграції з DataForSEO
import requests, json, base64
class DataForSEOClient:
BASE_URL = 'https://api.dataforseo.com/v3'
def __init__(self, login: str, password: str):
creds = base64.b64encode(f'{login}:{password}'.encode()).decode()
self.headers = {
'Authorization': f'Basic {creds}',
'Content-Type': 'application/json',
}
def check_positions(self, keyword, target_domain, location_code=2840, language_code='en', depth=100):
payload = [{
'keyword': keyword,
'target': target_domain,
'location_code': location_code,
'language_code': language_code,
'depth': depth,
}]
resp = requests.post(f'{self.BASE_URL}/serp/google/organic/live/advanced',
headers=self.headers, data=json.dumps(payload), timeout=60)
resp.raise_for_status()
return resp.json()
def parse_position(self, response, target_domain):
tasks = response.get('tasks', [])
if not tasks:
return None
items = tasks[0].get('result', [{}])[0].get('items', [])
for item in items:
if item.get('type') == 'organic' and target_domain in item.get('domain', ''):
return {'position': item.get('rank_absolute'), 'url': item.get('url'),
'title': item.get('title'), 'featured_snippet': item.get('rank_absolute') == 0}
return None
Структура бази даних для зберігання позицій
CREATE TABLE tracked_keywords (
id SERIAL PRIMARY KEY,
keyword TEXT NOT NULL,
target_domain TEXT NOT NULL,
search_engine VARCHAR(20) DEFAULT 'google',
location_code INTEGER,
language_code VARCHAR(10),
active BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE position_history (
id SERIAL PRIMARY KEY,
keyword_id INTEGER REFERENCES tracked_keywords(id),
position INTEGER,
url TEXT,
checked_at DATE NOT NULL,
UNIQUE(keyword_id, checked_at)
);
CREATE INDEX idx_positions_keyword_date ON position_history(keyword_id, checked_at DESC);
Щоденний запуск моніторингу та алерти
import psycopg2
from datetime import date
def run_daily_check(db_conn, dfs_client, target_domain):
today = date.today().isoformat()
with db_conn.cursor() as cur:
cur.execute('SELECT id, keyword, search_engine, location_code, language_code FROM tracked_keywords WHERE active = true')
keywords = cur.fetchall()
for kw_id, keyword, engine, loc_code, lang_code in keywords:
try:
response = dfs_client.check_positions(keyword=keyword, target_domain=target_domain,
location_code=loc_code or 2840, language_code=lang_code or 'en')
result = dfs_client.parse_position(response, target_domain)
position = result['position'] if result else None
url = result['url'] if result else None
with db_conn.cursor() as cur:
cur.execute('''
INSERT INTO position_history (keyword_id, position, url, checked_at)
VALUES (%s, %s, %s, %s)
ON CONFLICT (keyword_id, checked_at) DO UPDATE
SET position = EXCLUDED.position, url = EXCLUDED.url
''', (kw_id, position, url, today))
db_conn.commit()
except Exception as e:
print(f'Error checking {keyword}: {e}')
def detect_significant_changes(db_conn, threshold=5):
with db_conn.cursor() as cur:
cur.execute('''
WITH ranked AS (
SELECT k.keyword, p.position, p.checked_at,
LAG(p.position) OVER (PARTITION BY p.keyword_id ORDER BY p.checked_at) AS prev_position
FROM position_history p
JOIN tracked_keywords k ON k.id = p.keyword_id
WHERE p.checked_at >= CURRENT_DATE - INTERVAL '2 days'
)
SELECT keyword, prev_position, position,
(COALESCE(prev_position, 101) - COALESCE(position, 101)) AS change
FROM ranked
WHERE prev_position IS NOT NULL
AND ABS(COALESCE(prev_position, 101) - COALESCE(position, 101)) >= %s
ORDER BY ABS(change) DESC
''', (threshold,))
return [{'keyword': row[0], 'prev': row[1], 'current': row[2], 'change': row[3],
'direction': 'up' if row[3] > 0 else 'down'} for row in cur.fetchall()]
Нотифікації в Telegram
import httpx
def send_telegram_alert(bot_token, chat_id, changes):
if not changes:
return
lines = ['*Зміни позицій за добу:*\n']
for ch in changes[:20]:
arrow = '↑' if ch['direction'] == 'up' else '↓'
prev = ch['prev'] or '100+'
curr = ch['current'] or '100+'
lines.append(f"{arrow} `{ch['keyword']}`: {prev} → {curr}")
text = '\n'.join(lines)
httpx.post(f'https://api.telegram.org/bot{bot_token}/sendMessage',
json={'chat_id': chat_id, 'text': text, 'parse_mode': 'Markdown'})
Терміни та вартість
Налаштування моніторингу для одного домену зі зберіганням у PostgreSQL та Telegram-алертами займає 2–3 робочих дні. Додавання візуалізації (Grafana/Metabase), підтримки кількох сайтів та автоматичного імпорту ключових слів з Search Console — 4–6 днів. Вартість розраховується індивідуально виходячи з обсягу ключових слів та необхідних інтеграцій. Отримайте консультацію для точної оцінки.
DataForSEO SERP API документація
Додатково: Пошукові алгоритми Google — розуміння ранжування допомагає краще інтерпретувати дані моніторингу.







