File size: 7,945 Bytes
922fd01
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
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"
            )