Кластеризация ключей, контент-план, аудит
Начинаем с установки библиотек и загрузки семантического ядра. Ключевые слова можно взять из Google Search Console API, Ahrefs-экспорта или CSV-файла. Здесь используем CSV как универсальный формат.
# Установка зависимостей pip install openai pandas requests beautifulsoup4 lxml openpyxl python-dotenv import pandas as pd import os from dotenv import load_dotenv load_dotenv() # Загрузка семантического ядра из CSV # Формат CSV: keyword, volume, difficulty, cpc, intent df = pd.read_csv("semantic_core.csv") print(f"Загружено {len(df)} ключевых слов") print(df.head()) # Если данных нет — создаём тестовый датасет sample_data = { "keyword": ["купить ноутбук", "ноутбук для игр", "macbook pro цена", "лучший ноутбук 2026", "ноутбук для программиста"], "volume": [3200, 1800, 5400, 2900, 1100], "difficulty": [72, 65, 80, 45, 38] } df = pd.DataFrame(sample_data) df.to_csv("semantic_core.csv", index=False)
Ключевая задача SEO — сгруппировать тысячи ключей в тематические кластеры. Отправляем список ключей в OpenAI, модель возвращает группы с названиями. Результат — готовая структура сайта.
from openai import OpenAI import json client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) def cluster_keywords(keywords, max_clusters=8): """Группирует ключевые слова в тематические кластеры через OpenAI.""" kw_list = "\n".join(f"- {kw}" for kw in keywords) prompt = f"""Сгруппируй следующие ключевые слова в тематические кластеры. Максимум {max_clusters} кластеров. Для каждого кластера придумай название и главную страницу (URL-slug). Верни ТОЛЬКО JSON: {{ "clusters": [ {{"name": "Название кластера", "slug": "url-slug", "keywords": ["кв1", "кв2"]}} ] }} Ключевые слова: {kw_list}""" response = client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": prompt}], response_format={"type": "json_object"}, temperature=0.2 ) return json.loads(response.choices[0].message.content) keywords = df["keyword"].tolist() clusters = cluster_keywords(keywords) for c in clusters["clusters"]: print(f"\n📁 {c['name']} → /{c['slug']}/") for kw in c["keywords"]: print(f" • {kw}")
На основе кластеров и данных по частотности генерируем контент-план. Для каждого кластера AI предлагает: заголовки статей, мета-описания, рекомендуемую структуру и приоритет.
def generate_content_plan(clusters, domain="example.com"): """Генерирует контент-план: статьи, мета-теги, приоритеты.""" plan = [] for cluster in clusters["clusters"]: kws = ", ".join(cluster["keywords"]) prompt = f"""Для кластера "{cluster['name']}" (ключи: {kws}) создай контент-план из 3 статей. Для каждой статьи укажи: - title (H1, до 70 символов, с ключом) - meta_description (до 156 символов) - h2_structure (3-4 подзаголовка) - priority (high/medium/low) Верни ТОЛЬКО JSON-массив.""" response = client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": prompt}], response_format={"type": "json_object"}, temperature=0.4 ) articles = json.loads(response.choices[0].message.content) plan.append({"cluster": cluster["name"], "slug": cluster["slug"], "articles": articles}) return plan content_plan = generate_content_plan(clusters) # Сохраняем контент-план в Markdown with open("content_plan.md", "w") as f: f.write("# AI Контент-план\n\n") for cluster_plan in content_plan: f.write(f"## {cluster_plan['cluster']} → /{cluster_plan['slug']}/\n") for article in cluster_plan.get("articles", {}).get("articles", []): f.write(f"### {article.get('title','')}\n") f.write(f"*Meta: {article.get('meta_description','')}*\n") f.write(f"Приоритет: **{article.get('priority','medium')}**\n\n") print("✅ Контент-план сохранён в content_plan.md")
Парсим страницы сайта, извлекаем title, description, H1-H3, подсчитываем слова. Отправляем данные в AI — модель анализирует и даёт конкретные рекомендации по улучшению.
import requests from bs4 import BeautifulSoup def audit_page(url, target_keyword): """Парсит страницу и отправляет данные на AI-анализ.""" resp = requests.get(url, timeout=15, headers={ "User-Agent": "Mozilla/5.0 (compatible; SEOBot/1.0)" }) soup = BeautifulSoup(resp.text, "lxml") seo_data = { "url": url, "title": soup.title.string if soup.title else "", "title_length": len(soup.title.string) if soup.title else 0, "meta_desc": "", "h1": "", "h2_count": 0, "word_count": len(soup.get_text().split()), "has_schema": False, "images_without_alt": 0 } # Мета-описание meta = soup.find("meta", attrs={"name": "description"}) if meta: seo_data["meta_desc"] = meta.get("content", "") # H1 h1 = soup.find("h1") if h1: seo_data["h1"] = h1.get_text(strip=True) # H2 seo_data["h2_count"] = len(soup.find_all("h2")) # Schema.org seo_data["has_schema"] = bool(soup.find_all("script", type="application/ld+json")) # Изображения без alt seo_data["images_without_alt"] = len([ img for img in soup.find_all("img") if not img.get("alt") ]) return seo_data page = audit_page("https://example.com/blog/seo-guide", "seo оптимизация") print(json.dumps(page, indent=2, ensure_ascii=False))
Отправляем результаты аудита в OpenAI — модель анализирует метрики и выдаёт конкретные рекомендации: что исправить в заголовках, структуре, контенте. Оценка по 100-балльной шкале.
def ai_seo_recommendations(page_data, target_kw): """AI-анализ SEO-метрик и генерация рекомендаций.""" prompt = f"""Ты — senior SEO-специалист. Проанализируй страницу: URL: {page_data['url']} Title ({page_data['title_length']} зн): {page_data['title']} Meta Description: {page_data['meta_desc']} H1: {page_data['h1']} H2 (количество): {page_data['h2_count']} Слов: {page_data['word_count']} Schema.org: {page_data['has_schema']} Изображений без alt: {page_data['images_without_alt']} Целевой ключ: {target_kw} Дай оценку от 0 до 100 и список конкретных улучшений. Верни JSON: {{ "score": число, "issues": [{{"severity": "critical|warning|info", "element": "...", "problem": "...", "fix": "..."}}], "summary": "общий вывод в 2-3 предложениях" }}""" response = client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": prompt}], response_format={"type": "json_object"}, temperature=0.2 ) return json.loads(response.choices[0].message.content) result = ai_seo_recommendations(page, "seo оптимизация") print(f"📊 SEO Score: {result['score']}/100") for issue in result["issues"]: icon = "🔴" if issue["severity"] == "critical" else "🟡" if issue["severity"] == "warning" else "ℹ️" print(f"{icon} [{issue['element']}] {issue['problem']}") print(f" 💡 {issue['fix']}") print(f"\n📝 {result['summary']}")
Вместо ручного аудита одной страницы — прогоняем весь сайт. Парсим sitemap.xml, для каждой страницы запускаем аудит, сохраняем результаты в Excel для анализа.
import xml.etree.ElementTree as ET from urllib.parse import urlparse def parse_sitemap(sitemap_url): """Извлекает все URL из sitemap.xml.""" resp = requests.get(sitemap_url, timeout=30) root = ET.fromstring(resp.content) ns = {"sm": "http://www.sitemaps.org/schemas/sitemap/0.9"} return [el.text for el in root.findall(".//sm:loc", ns)] urls = parse_sitemap("https://example.com/sitemap.xml") print(f"Найдено {len(urls)} URL в sitemap") # Массовый аудит (первые 10 страниц для демо) results = [] for url in urls[:10]: try: page_data = audit_page(url, "") ai_result = ai_seo_recommendations(page_data, "") results.append({ "url": url, "score": ai_result["score"], "issues_count": len(ai_result["issues"]), "title_length": page_data["title_length"], "word_count": page_data["word_count"] }) print(f"✅ {url} — {ai_result['score']}/100") except Exception as e: print(f"❌ {url} — {e}") # Сохраняем в Excel pd.DataFrame(results).to_excel("seo_audit_report.xlsx", index=False) print("\n✅ Отчёт сохранён в seo_audit_report.xlsx")
Подключаемся к Google Search Console API для получения реальных поисковых запросов, по которым сайт показывается в выдаче. Данные используем для кластеризации и контент-плана.
# pip install google-api-python-client google-auth-oauthlib from google.oauth2 import service_account from googleapiclient.discovery import build # Сервисный аккаунт Google Cloud с доступом к Search Console SERVICE_ACCOUNT_FILE = "service_account.json" SITE_URL = "https://example.com/" credentials = service_account.Credentials.from_service_account_file( SERVICE_ACCOUNT_FILE, scopes=["https://www.googleapis.com/auth/webmasters.readonly"] ) service = build("searchconsole", "v1", credentials=credentials) # Запрос: топ-500 запросов за последние 28 дней request_body = { "startDate": "2026-05-13", "endDate": "2026-06-10", "dimensions": ["query"], "rowLimit": 500 } response = service.searchanalytics().query( siteUrl=SITE_URL, body=request_body ).execute() queries = [] for row in response.get("rows", []): queries.append({ "keyword": row["keys"][0], "clicks": row["clicks"], "impressions": row["impressions"], "ctr": round(row["ctr"] * 100, 2), "position": round(row["position"], 1) }) df_gsc = pd.DataFrame(queries) df_gsc.to_csv("gsc_queries.csv", index=False) print(f"Собрано {len(queries)} запросов из GSC") print(df_gsc.nlargest(5, "impressions")[["keyword", "clicks", "position"]])
Вы построили полноценный AI-SEO пайплайн на Python. Система умеет: собирать ключевые слова из Google Search Console и CSV, кластеризовать их через OpenAI, генерировать контент-план с заголовками и мета-описаниями, парсить и аудировать страницы сайта, выдавать AI-рекомендации с оценкой по 100-балльной шкале. Все результаты сохраняются в Excel и Markdown для удобной передачи команде. Этот пайплайн заменяет недели ручной работы SEO-специалиста и делает её за 5–10 минут на中型 сайт. Для масштабирования добавьте асинхронные запросы (asyncio + aiohttp) — тогда аудит 1000 страниц займёт менее минуты.