TedTalks / app.py
TamerTokgoz's picture
Update app.py
935c14d verified
import streamlit as st
import requests
from bs4 import BeautifulSoup
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.feature_extraction.text import TfidfVectorizer
import numpy as np
# --- VERİ ÇEKME FONKSİYONU ---
def scrape_ted_ideas(category, pages=1):
# Eğer kategori 'all' ise tüm ana kategorileri tara
categories_to_scrape = [category]
if category == "all":
categories_to_scrape = ["tech", "business", "science", "arts-design", "we-humans"]
all_data = []
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"}
for cat in categories_to_scrape:
for page in range(1, pages + 1):
url = f"https://ideas.ted.com/category/{cat}/page/{page}/"
try:
response = requests.get(url, headers=headers, timeout=10)
if response.status_code != 200:
continue
soup = BeautifulSoup(response.content, "html.parser")
articles = soup.find_all("div", class_="post")
for art in articles:
title_tag = art.find("h1")
excerpt_tag = art.find("div", class_="entry-excerpt")
if title_tag:
title = title_tag.text.strip()
excerpt = excerpt_tag.text.strip() if excerpt_tag else ""
all_data.append({
"title": title,
"excerpt": excerpt,
"category": cat
})
except Exception as e:
continue
return pd.DataFrame(all_data)
# --- STREAMLIT ARAYÜZÜ (YAN MENÜSÜZ) ---
st.set_page_config(page_title="TED Ideas NLP Analyzer", layout="wide")
st.title("💡 TED Ideas NLP Content Analyzer")
st.markdown("TED Ideas platformundaki makaleleri kategorilerine göre çeker ve en önemli kavramları analiz eder.")
# Ana ekranda kontroller (Yan menü yerine sütunlar kullanıyoruz)
col_ctrl1, col_ctrl2, col_ctrl3 = st.columns([2, 1, 1])
with col_ctrl1:
category_list = ["all", "tech", "business", "science", "arts-design", "we-humans"]
selected_category = st.selectbox("Kategori Seçin", category_list, index=0, help="'all' seçeneği tüm kategorileri tarar.")
with col_ctrl2:
page_count = st.number_input("Sayfa Sayısı (Her kategori için)", min_value=1, max_value=5, value=1)
with col_ctrl3:
n_gram_choice = st.radio("Analiz Tipi", ["Tekli Kelimeler", "Kelime Grupları (2'li)"])
analyze_button = st.button("Analizi Başlat", use_container_width=True)
if analyze_button:
with st.spinner('Veriler toplanıyor ve NLP analizi yapılıyor... Lütfen bekleyin.'):
# 1. Veri Kazıma
df = scrape_ted_ideas(selected_category, page_count)
if not df.empty:
# Metin birleştirme ve temizlik
df['combined_text'] = df['title'] + " " + df['excerpt']
# Boş satırları temizle
df = df[df['combined_text'].str.strip() != ""]
n_range = (1, 1) if n_gram_choice == "Tekli Kelimeler" else (2, 2)
try:
# 2. TF-IDF Analizi (Daha esnek parametrelerle)
vectorizer = TfidfVectorizer(
stop_words='english',
ngram_range=n_range,
min_df=1,
token_pattern=r"(?u)\b\w\w+\b" # En az 2 harfli kelimeler
)
tfidf_matrix = vectorizer.fit_transform(df['combined_text'])
# Kelime ağırlıklarını hesapla
importance = np.asarray(tfidf_matrix.mean(axis=0)).ravel()
word_freq = pd.DataFrame({'word': vectorizer.get_feature_names_out(), 'importance': importance})
top_words = word_freq.sort_values(by='importance', ascending=False).head(15)
# 3. Sonuçları Göster
st.divider()
res_col1, res_col2 = st.columns([1, 1])
with res_col1:
st.subheader(f"📊 Veri Özeti ({len(df)} Makale)")
st.dataframe(df[['category', 'title', 'excerpt']].head(20), use_container_width=True)
with res_col2:
st.subheader("🎯 En Önemli Kavramlar (TF-IDF)")
if not top_words.empty:
fig, ax = plt.subplots(figsize=(10, 6))
sns.barplot(data=top_words, x='importance', y='word', palette='magma', ax=ax)
plt.title(f"Kategori: {selected_category.upper()}")
plt.xlabel("Önem Skoru")
plt.ylabel("Kavramlar")
st.pyplot(fig)
else:
st.warning("Görselleştirilecek veri bulunamadı.")
except ValueError:
st.error("Hata: Çekilen metin içeriği analiz için yetersiz (çok kısa veya sadece duraklama kelimeleri içeriyor).")
st.info("Çözüm: Sayfa sayısını artırarak daha fazla veri çekmeyi deneyin.")
else:
st.error("⚠️ Veri çekilemedi. Siteye erişim engellenmiş olabilir veya kategori boş dönüyor.")