faaaa / app.py
coingimp's picture
Create app.py
922fd01 verified
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"""
<h1>SEO Report - {target_keyword}</h1>
<p>Date: {datetime.now()}</p>
<p>Similarity: {similarity:.2f}%</p>
<h2>Missing Aspects:</h2>
<ul>{''.join([f'<li>{m}</li>' for m in missing_aspects])}</ul>
<h2>AI Recommendations:</h2>
{''.join(recommendations)}
"""
st.download_button(
label="📥 Скачать HTML отчет",
data=report_text,
file_name="seo_report.html",
mime="text/html"
)