import streamlit as st import numpy as np from sentence_transformers import SentenceTransformer, util import openai from datetime import datetime # --- НАСТРОЙКИ СТРАНИЦЫ --- st.set_page_config(layout="wide", page_title="SEO Intent Analyzer Pro") # --- КЭШИРОВАНИЕ МОДЕЛИ (Чтобы не загружать 400мб каждый раз) --- @st.cache_resource def load_model(): return SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2') try: model = load_model() except Exception as e: st.error(f"Ошибка загрузки модели: {e}") # --- ИНТЕРФЕЙС: БОКОВАЯ ПАНЕЛЬ --- st.sidebar.title("⚙️ Настройки") language = st.sidebar.selectbox( "Язык анализа", ["English", "Hindi", "Spanish", "Bengali"] ) api_key = st.sidebar.text_input("OpenAI API Key (для рекомендаций)", type="password") target_keyword = st.sidebar.text_input("Целевой Интент / Ключ", "online casino guide") st.sidebar.markdown("---") st.sidebar.info("Загрузите тексты конкурентов и свой текст, затем нажмите 'Анализировать'.") # --- ИНТЕРФЕЙС: ОСНОВНАЯ ЧАСТЬ --- st.title("🚀 Анализатор Интента (SBERT + AI)") col1, col2 = st.columns(2) with col1: st.subheader("📝 Ваш Текст") user_text = st.text_area("Вставьте ваш контент сюда", height=400) with col2: st.subheader("🕵️ Конкуренты") # Используем табы для конкурентов, чтобы не загромождать экран tabs = st.tabs([f"Конкурент {i+1}" for i in range(5)]) competitors = [] for i, tab in enumerate(tabs): with tab: comp_text = st.text_area(f"Текст конкурента {i+1}", height=320, key=f"comp_{i}") if len(comp_text) > 50: competitors.append(comp_text) # --- ЛОГИКА АНАЛИЗА --- if st.button("🚀 ЗАПУСТИТЬ АНАЛИЗ", type="primary"): if not user_text: st.warning("Пожалуйста, введите ваш текст.") elif not competitors: st.warning("Пожалуйста, добавьте хотя бы одного конкурента.") else: with st.spinner('Загрузка нейросети и сравнение векторов...'): # 1. Анализ SBERT user_emb = model.encode(user_text, convert_to_tensor=True) comp_embs = [model.encode(c, convert_to_tensor=True) for c in competitors] # Средний вектор конкурентов avg_comp_emb = np.mean([c.cpu().numpy() for c in comp_embs], axis=0) # Сходство similarity = util.cos_sim(user_emb, avg_comp_emb).item() * 100 # 2. Поиск упущенных аспектов (Gap Analysis) user_sentences = user_text.split('.') # Собираем все предложения конкурентов в кучу comp_sentences_flat = [] for c in competitors: comp_sentences_flat.extend([s for s in c.split('.') if len(s) > 30]) # Кодируем предложения user_sent_embs = model.encode(user_sentences, convert_to_tensor=True) comp_sent_embs = model.encode(comp_sentences_flat, convert_to_tensor=True) # Матрица схожести cos_scores = util.cos_sim(comp_sent_embs, user_sent_embs) missing_aspects = [] # Если предложение конкурента не похоже ни на одно наше (score < 0.45) for idx, scores in enumerate(cos_scores): if scores.max() < 0.45: missing_aspects.append(comp_sentences_flat[idx].strip()) # Убираем дубли и берем топ-5 missing_aspects = list(set(missing_aspects))[:5] # 3. AI Рекомендации recommendations = [] if api_key and missing_aspects: openai.api_key = api_key status_text = st.empty() status_text.text("Генерация рекомендаций через GPT...") for aspect in missing_aspects: prompt = f""" Role: Expert SEO Copywriter. Language: {language}. Task: My competitors mention: "{aspect}", but I missed it. Action: Write a paragraph (HTML format) to insert into my article to cover this topic. """ try: response = openai.ChatCompletion.create( model="gpt-3.5-turbo", messages=[{"role": "user", "content": prompt}], max_tokens=300 ) recommendations.append(response.choices[0].message.content) except Exception as e: st.error(f"AI Error: {e}") status_text.empty() # --- ВЫВОД РЕЗУЛЬТАТОВ --- st.divider() st.header("📊 Результаты Анализа") # Метрики m1, m2, m3 = st.columns(3) m1.metric("Сходство с Топом", f"{similarity:.1f}%") m2.metric("Длина вашего текста", f"{len(user_text.split())} слов") m3.metric("Среднее у конкурентов", f"{int(np.mean([len(c.split()) for c in competitors]))} слов") # Визуализация прогресса st.write("Шкала раскрытия интента:") st.progress(min(int(similarity), 100)) # Таблица сравнения col_res1, col_res2 = st.columns(2) with col_res1: st.subheader("⚠️ Упущенные аспекты (Gaps)") if missing_aspects: for gap in missing_aspects: st.error(f"У конкурентов: \"{gap}\"") else: st.success("Явных пробелов в интенте не найдено!") with col_res2: st.subheader("💡 Рекомендации к внедрению") if recommendations: for rec in recommendations: st.code(rec, language="html") st.caption("Скопируйте код выше и вставьте в статью") elif not api_key: st.info("Введите API Key слева, чтобы получить готовый текст исправлений.") else: st.info("Рекомендации не требуются.") # Экспорт report_text = f"""

SEO Report - {target_keyword}

Date: {datetime.now()}

Similarity: {similarity:.2f}%

Missing Aspects:

AI Recommendations:

{''.join(recommendations)} """ st.download_button( label="📥 Скачать HTML отчет", data=report_text, file_name="seo_report.html", mime="text/html" )