Spaces:
Sleeping
Sleeping
File size: 6,804 Bytes
64db1cd bdbc2da b6549ee 26c78a4 64db1cd b6549ee af1173c 64db1cd b6549ee 64db1cd 6ce99f0 64db1cd b6549ee 64db1cd ace5c70 64db1cd b6549ee 64db1cd b6549ee 6ce99f0 b6549ee 6ce99f0 64db1cd 6ce99f0 64db1cd 6ce99f0 64db1cd 6ce99f0 64db1cd 6ce99f0 64db1cd 6ce99f0 64db1cd 6ce99f0 64db1cd 6ce99f0 64db1cd 12216f2 f5fe94e 64db1cd b6549ee 64db1cd 6ce99f0 64db1cd b6549ee 64db1cd ace5c70 64db1cd ace5c70 64db1cd |
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 175 176 177 178 179 180 181 182 183 184 185 186 |
import gradio as gr
import pandas as pd
from googleapiclient.discovery import build
import plotly.express as px
import base64
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import KMeans
from datetime import datetime, timedelta
import os
from huggingface_hub import InferenceClient # Hugging Face Hub API μ¬μ©
# μ¬κΈ°μ YouTube API ν€λ₯Ό μ
λ ₯νμΈμ
YOUTUBE_API_KEY = "AIzaSyA9DEIHCYexeF2gSFW8cF6E3JTu9BhYxLc"
def create_client(model_name):
token = os.getenv("HF_TOKEN")
return InferenceClient(model=model_name, token=token)
client = create_client("CohereForAI/c4ai-command-r-plus")
def get_video_stats(video_id):
youtube = build("youtube", "v3", developerKey=YOUTUBE_API_KEY)
video_response = youtube.videos().list(
part="snippet,statistics",
id=video_id
).execute()
video = video_response["items"][0]
title = video["snippet"]["title"]
channel_id = video["snippet"]["channelId"]
publish_time = video["snippet"]["publishedAt"]
view_count = int(video["statistics"].get("viewCount", 0))
like_count = int(video["statistics"].get("likeCount", 0))
comment_count = int(video["statistics"].get("commentCount", 0))
return {
"λμμ ID": video_id,
"μ λͺ©": title,
"κ²μ μκ°": publish_time,
"μ±λ ID": channel_id,
"μ‘°νμ": view_count,
"μ’μμ μ": like_count,
"λκΈ μ": comment_count
}
def get_channel_stats(channel_id):
youtube = build("youtube", "v3", developerKey=YOUTUBE_API_KEY)
channel_response = youtube.channels().list(
part="statistics",
id=channel_id
).execute()
if channel_response["items"]:
channel = channel_response["items"][0]
subscriber_count = int(channel["statistics"]["subscriberCount"])
else:
subscriber_count = 0
return subscriber_count
def get_video_data(query, max_results, published_after, published_before):
youtube = build("youtube", "v3", developerKey=YOUTUBE_API_KEY)
video_ids = []
next_page_token = None
while len(video_ids) < max_results:
search_response = youtube.search().list(
q=query,
type="video",
part="id",
maxResults=50,
pageToken=next_page_token,
order="viewCount",
publishedAfter=published_after,
publishedBefore=published_before
).execute()
video_ids.extend([item["id"]["videoId"] for item in search_response["items"]])
next_page_token = search_response.get("nextPageToken")
if not next_page_token:
break
video_ids = video_ids[:max_results]
video_stats = []
for video_id in video_ids:
stats = get_video_stats(video_id)
channel_id = stats["μ±λ ID"]
subscriber_count = get_channel_stats(channel_id)
stats["ꡬλ
μ μ"] = subscriber_count
video_stats.append(stats)
video_stats_df = pd.DataFrame(video_stats)
return video_stats_df
def download_csv(df, filename):
csv = df.to_csv(index=False)
b64 = base64.b64encode(csv.encode()).decode()
href = f'<a href="data:file/csv;base64,{b64}" download="{filename}.csv">λ€μ΄λ‘λ {filename} CSV</a>'
return href
def visualize_video_ranking(video_stats_df):
video_stats_df["νμ± μ§μ"] = video_stats_df["μ‘°νμ"] / video_stats_df["ꡬλ
μ μ"]
csv_download_link = download_csv(video_stats_df, "video_stats")
fig = px.bar(video_stats_df, x="λμμ ID", y="νμ± μ§μ", color="μ‘°νμ",
labels={"λμμ ID": "λμμ ID", "νμ± μ§μ": "νμ± μ§μ"},
title="λμμ νμ± μ§μ")
fig.update_layout(height=500, width=500)
return video_stats_df, fig, csv_download_link
def analyze_titles(video_stats_df, n_clusters=5):
titles = video_stats_df['μ λͺ©'].tolist()
vectorizer = TfidfVectorizer()
tfidf_matrix = vectorizer.fit_transform(titles)
kmeans = KMeans(n_clusters=n_clusters, random_state=42)
kmeans.fit(tfidf_matrix)
labels = kmeans.labels_
video_stats_df["ν΄λ¬μ€ν°"] = labels
cluster_summaries = []
for i in range(n_clusters):
cluster_titles = video_stats_df[video_stats_df["ν΄λ¬μ€ν°"] == i]['μ λͺ©'].tolist()
cluster_text = ' '.join(cluster_titles)
summary = summarize_cluster(cluster_text, i)
cluster_summaries.append(summary)
cluster_summary_df = pd.DataFrame({'ν΄λ¬μ€ν°': range(n_clusters), 'μμ½': cluster_summaries})
return cluster_summary_df
def summarize_cluster(cluster_text, cluster_num):
prompt = f"λ€μ λμμμ λΆμνμ¬ μμ½νκ³ , 500μ μ΄λ΄λ‘ λμμμ νΉμ§ λ° μΈκΈ° μμΈμ μ€λͺ
ν΄μ£ΌμΈμ: {cluster_text}"
response = client.generate(inputs=prompt)
summary = response.generated_text.strip()
return summary
def main(query, max_results, period, page, n_clusters=5):
if query:
# κΈ°κ° μ€μ
now = datetime.utcnow()
published_before = now.isoformat("T") + "Z"
if period == "1μ£ΌμΌ":
published_after = (now - timedelta(days=7)).isoformat("T") + "Z"
elif period == "1κ°μ":
published_after = (now - timedelta(days=30)).isoformat("T") + "Z"
elif period == "3κ°μ":
published_after = (now - timedelta(days=90)).isoformat("T") + "Z"
else:
published_after = (now - timedelta(days=30)).isoformat("T") + "Z" # κΈ°λ³Έκ° 1κ°μ
video_stats_df = get_video_data(query, max_results, published_after, published_before)
if page == "Video Ranking":
video_stats_df, fig, csv_download_link = visualize_video_ranking(video_stats_df)
return video_stats_df, fig, csv_download_link
elif page == "Title Analysis":
cluster_summary_df = analyze_titles(video_stats_df, n_clusters)
return cluster_summary_df, None, None
iface = gr.Interface(
fn=main,
inputs=[
gr.components.Textbox(label="κ²μ 쿼리"),
gr.components.Number(label="μ΅λ κ²°κ³Ό μ", value=5, precision=0, minimum=1, maximum=1000),
gr.components.Dropdown(["1μ£ΌμΌ", "1κ°μ", "3κ°μ"], label="κΈ°κ°"),
gr.components.Dropdown(["Video Ranking", "Title Analysis"], label="νμ΄μ§"),
gr.components.Number(label="ν΄λ¬μ€ν° μ", value=5, precision=0, minimum=2, maximum=10)
],
outputs=[
gr.components.Dataframe(label="κ²°κ³Ό"),
gr.components.Plot(label="κ·Έλν"),
gr.components.HTML(label="CSV λ€μ΄λ‘λ λ§ν¬")
],
live=False,
title="YouTube λΆμ λꡬ"
)
if __name__ == "__main__":
iface.launch()
|