therayz1's picture
app.py
9e8e8c1 verified
import gradio as gr
from googleapiclient.discovery import build
from textblob import TextBlob
import pandas as pd
import plotly.express as px
import re
# Türkçe pozitif ve negatif kelimeler sözlüğü
POSITIVE_WORDS = {
'teşekkür', 'güzel', 'harika', 'muhteşem', 'süper', 'başarılı', 'mükemmel',
'eğitici', 'faydalı', 'yararlı', 'iyi', 'sevdim', 'beğendim', 'bravo',
'tebrik', 'excellent', 'great', 'awesome', 'amazing', 'thanks'
}
NEGATIVE_WORDS = {
'kötü', 'berbat', 'rezalet', 'saçma', 'gereksiz', 'boş', 'yanlış',
'hata', 'zayıf', 'olmamış', 'beğenmedim', 'sevmedim', 'waste', 'bad',
'terrible', 'worst', 'poor', 'boring'
}
def get_video_id(url):
"""YouTube URL'sinden video ID'sini çıkarır."""
if "v=" in url:
return url.split("v=")[1].split("&")[0]
elif "youtu.be" in url:
return url.split("/")[-1]
return None
def clean_text(text):
"""Metni temizler ve normalleştirir."""
text = re.sub(r'<.*?>', '', text) # HTML etiketlerini kaldır
text = re.sub(r'http\S+|www.\S+', '', text) # URL'leri kaldır
text = text.lower() # Küçük harfe çevir
return text.strip()
def analyze_sentiment_improved(text):
"""Geliştirilmiş duygu analizi."""
text = clean_text(text)
words = text.split() # Basit kelime bölme
# Pozitif ve negatif kelime sayısını hesapla
positive_count = sum(1 for word in words if word.lower() in POSITIVE_WORDS)
negative_count = sum(1 for word in words if word.lower() in NEGATIVE_WORDS)
# TextBlob ile duygu analizi
blob_sentiment = TextBlob(text).sentiment.polarity
# Skorları birleştirerek sonuç üret
if positive_count > negative_count or blob_sentiment > 0.1:
return "Pozitif"
elif negative_count > positive_count or blob_sentiment < -0.1:
return "Negatif"
return "Nötr"
def count_search_word(text, search_word):
"""Aranan kelimenin metinde kaç kez geçtiğini sayar."""
if not search_word:
return 0
text = clean_text(text)
search_word = search_word.lower()
return text.count(search_word)
def analyze_video(api_key, video_url, search_word=""):
"""Video istatistiklerini ve yorumları analiz eder."""
try:
youtube = build('youtube', 'v3', developerKey=api_key)
video_id = get_video_id(video_url)
if not video_id:
return "Geçersiz YouTube URL'si", None, None, None
# Video detaylarını al
video_response = youtube.videos().list(
part='statistics,snippet',
id=video_id
).execute()
if not video_response['items']:
return "Video bulunamadı", None, None, None
statistics = video_response['items'][0]['statistics']
video_title = video_response['items'][0]['snippet']['title']
# Yorumları al
comments = []
nextPageToken = None
total_search_word_count = 0
while True:
comment_response = youtube.commentThreads().list(
part='snippet',
videoId=video_id,
maxResults=100,
pageToken=nextPageToken
).execute()
for item in comment_response['items']:
comment_text = item['snippet']['topLevelComment']['snippet']['textDisplay']
author = item['snippet']['topLevelComment']['snippet']['authorDisplayName']
like_count = item['snippet']['topLevelComment']['snippet'].get('likeCount', 0)
published_at = item['snippet']['topLevelComment']['snippet']['publishedAt']
search_word_count = count_search_word(comment_text, search_word)
sentiment = analyze_sentiment_improved(comment_text)
total_search_word_count += search_word_count
if not search_word or search_word_count > 0:
comments.append({
'Yazar': author,
'Yorum': comment_text,
'Duygu': sentiment,
'Beğeni': like_count,
'Tarih': published_at,
f'"{search_word}" Kelime Sayısı': search_word_count if search_word else 0
})
nextPageToken = comment_response.get('nextPageToken')
if not nextPageToken:
break
# DataFrame oluştur
df = pd.DataFrame(comments)
# Duygu analizi istatistikleri
sentiment_stats = df['Duygu'].value_counts()
# Plotly ile grafik oluştur
fig = px.bar(
x=sentiment_stats.index,
y=sentiment_stats.values,
title=f"Duygu Analizi Sonuçları - {video_title}",
labels={'x': 'Duygu', 'y': 'Yorum Sayısı'},
color=sentiment_stats.index,
color_discrete_map={
'Pozitif': 'green',
'Negatif': 'red',
'Nötr': 'gray'
}
)
# Excel dosyası oluştur
excel_path = "youtube_comments.xlsx"
df.to_excel(excel_path, index=False)
# Sonuçları formatla
stats_text = f"""
Video Başlığı: {video_title}
Video İstatistikleri:
- Görüntülenme: {statistics.get('viewCount', 'Bilgi yok')}
- Beğeni: {statistics.get('likeCount', 'Bilgi yok')}
- Yorum Sayısı: {statistics.get('commentCount', 'Bilgi yok')}
Yorum Duygu Analizi:
- Pozitif Yorum: {sentiment_stats.get('Pozitif', 0)}
- Negatif Yorum: {sentiment_stats.get('Negatif', 0)}
- Nötr Yorum: {sentiment_stats.get('Nötr', 0)}
"""
if search_word:
stats_text += f"""
Aranan Kelime "{search_word}":
- Toplam Kullanım Sayısı: {total_search_word_count}
- İçeren Yorum Sayısı: {len([c for c in comments if c[f'"{search_word}" Kelime Sayısı'] > 0])}
"""
return stats_text, df, fig, excel_path
except Exception as e:
return f"Hata oluştu: {str(e)}", None, None, None
# Gradio arayüzü
def gradio_interface(api_key, video_url, search_word=""):
stats, df, plot, excel_path = analyze_video(api_key, video_url, search_word)
return stats, df, plot, excel_path
# Gradio uygulamasını oluştur
iface = gr.Interface(
fn=gradio_interface,
inputs=[
gr.Textbox(label="YouTube API Anahtarı (Youtube API Key)"),
gr.Textbox(label="YouTube Video URL'si (Youtube Video URL)"),
gr.Textbox(label="Yorum İçinde Aranacak Kelime (Word to Search in Comment)")
],
outputs=[
gr.Textbox(label="İstatistikler(Statistics)"),
gr.Dataframe(label="Yorumlar ve Duygu Analizi(Comments and Sentiment Analysis)"),
gr.Plot(label="Duygu Analizi Grafiği(Sentiment Analysis Chart)"),
gr.File(label="Yorumları İndir (Excel)(Download comments Excel)")
],
title="YouTube Video Analiz Aracı(Youtube Video Analysis Tool)--->(Deployed by Eray Coşkun)",
description="Video istatistiklerini ve yorum duygu analizini görüntüleyin(View video statistics and comment sentiment analysis)"
)
# Uygulamayı başlat
if __name__ == "__main__":
iface.launch(share=True)