-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
174 lines (134 loc) · 5.9 KB
/
Copy pathapp.py
File metadata and controls
174 lines (134 loc) · 5.9 KB
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 re
import emoji
from googleapiclient.discovery import build
from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
import matplotlib.pyplot as plt
API_KEY = 'xxxxxxxxxxxxxxxxxxxxxx' # Put in your API Key
youtube = build('youtube', 'v3', developerKey=API_KEY) # Initializing Youtube API
# Taking input from the user and slicing for video id
video_id = input('Enter Youtube Video URL: ')[-11:]
print("Video ID: " + video_id)
# Getting the channelId of the video uploader
video_response = youtube.videos().list(part='snippet', id=video_id).execute()
# Splitting the response for channelID
video_snippet = video_response['items'][0]['snippet']
uploader_channel_id = video_snippet['channelId']
print("Channel ID: " + uploader_channel_id)
# Fetch comments and filter out those by the uploader and non-English comments
print("Fetching Comments...")
comments = []
nextPageToken = None
def is_english(comment_text):
# Filter out non-English comments by checking the Unicode range for English characters
return re.match(r'^[\x00-\x7F]+$', comment_text) is not None
try:
# Loop until we have at least 600 comments or until we run out of comments to fetch
while len(comments) < 200:
request = youtube.commentThreads().list(
part='snippet',
videoId=video_id,
maxResults=100, # Fetch up to 100 comments per request
pageToken=nextPageToken
)
response = request.execute()
# Loop through the items (comments) in the response
for item in response['items']:
comment = item['snippet']['topLevelComment']['snippet']
# Check if the comment is not from the video uploader and is in English
comment_text = comment['textDisplay']
if comment['authorChannelId']['value'] != uploader_channel_id and is_english(comment_text):
comments.append(comment_text)
nextPageToken = response.get('nextPageToken')
if not nextPageToken:
break
except Exception as e:
print("Error occurred:", str(e))
# Display the first 5 fetched comments, if any
if comments:
print("First 5 comments (English only, excluding uploader):")
for i, comment in enumerate(comments[:5], start=1):
print(f"{i}: {comment}")
else:
print("No comments fetched.")
# Define a pattern to match hyperlinks
hyperlink_pattern = re.compile(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+')
# Define the threshold ratio for filtering emojis
threshold_ratio = 0.65
# List to store relevant comments
relevant_comments = []
# Loop through each comment in the fetched comments
for comment_text in comments:
# Convert comment to lowercase and remove leading/trailing spaces
comment_text = comment_text.lower().strip()
# Count the number of emojis in the comment
emojis = emoji.emoji_count(comment_text)
# Count text characters (excluding spaces)
text_characters = len(re.sub(r'\s', '', comment_text))
# Check if the comment contains any alphanumeric characters and no hyperlinks
if (any(char.isalnum() for char in comment_text)) and not hyperlink_pattern.search(comment_text):
# Filter out comments that are mostly emojis
if emojis == 0 or (text_characters / (text_characters + emojis)) > threshold_ratio:
relevant_comments.append(comment_text)
# Print the first 5 relevant comments
print("First 5 relevant comments:")
for i, comment in enumerate(relevant_comments[:5], start=1):
print(f"{i}: {comment}")
# Write relevant comments to a file
with open("ytcomments.txt", 'w', encoding='utf-8') as f:
for idx, comment in enumerate(relevant_comments):
f.write(str(comment) + "\n")
print("Comments stored successfully!")
# Function to analyze sentiment scores and append to polarity
def sentiment_scores(comment, polarity):
sentiment_object = SentimentIntensityAnalyzer()
sentiment_dict = sentiment_object.polarity_scores(comment)
polarity.append(sentiment_dict['compound'])
return polarity
polarity = []
positive_comments = []
negative_comments = []
neutral_comments = []
# Read comments from the file
with open("ytcomments.txt", 'r', encoding='utf-8') as f:
comments = f.readlines()
# Analyze the comments
print("Analyzing Comments...")
for comment in comments:
polarity = sentiment_scores(comment, polarity)
if polarity[-1] > 0.05:
positive_comments.append(comment)
elif polarity[-1] < -0.05:
negative_comments.append(comment)
else:
neutral_comments.append(comment)
print("Polarity scores:", polarity[:5])
# Calculate the average polarity score
avg_polarity = sum(polarity) / len(polarity)
print("Average Polarity:", avg_polarity)
# Categorize the video response based on average polarity
if avg_polarity > 0.05:
print("The Video has a Positive response")
elif avg_polarity < -0.05:
print("The Video has a Negative response")
else:
print("The Video has a Neutral response")
# Find the most positive and most negative comments
most_positive_comment = comments[polarity.index(max(polarity))]
most_negative_comment = comments[polarity.index(min(polarity))]
print("Most Positive Comment:", most_positive_comment.strip(), "Score:", max(polarity))
print("Most Negative Comment:", most_negative_comment.strip(), "Score:", min(polarity))
# Count positive, negative, and neutral comments
positive_count = len(positive_comments)
negative_count = len(negative_comments)
neutral_count = len(neutral_comments)
# Bar Chart
plt.bar(['Positive', 'Negative', 'Neutral'], [positive_count, negative_count, neutral_count], color=['blue', 'red', 'grey'])
plt.xlabel('Sentiment')
plt.ylabel('Comment Count')
plt.title('Sentiment Analysis of Comments')
plt.show()
# Pie Chart
plt.figure(figsize=(10, 6))
plt.pie([positive_count, negative_count, neutral_count], labels=['Positive', 'Negative', 'Neutral'], autopct='%1.1f%%', startangle=90)
plt.axis('equal')
plt.show()