Sentimen
Analisis pada Komentar Youtube Menggunakan Python
Opinion Mining / Sentiment Analysis
(sebagian besar researcher menganggap dua istilah ini sama/interchangeable)
merupakan sebuah cabang penelitian di domain Text Mining yang mulai booming
pada awal tahun 2002-an. Riset-nya mulai marak semenjak paper dari B.Pang dan
L.Lee [1] keluar. Secara umum, Sentiment analysis ini dibagi menjadi 2 kategori
besar :
1. Coarse-grained
sentiment analysis
2. Fined-grained
sentiment analysis
Coarse-grained sentiment analysis - kita
mencoba melakukan proses analysis pada level Dokumen. Singkatnya adalah kita
mencoba mengklasifikasikan orientasi sebuah dokumen secara keseluruhan.
Orientasi ini ada 3 jenih : Positif, Netral, Negatif. Akan tetapi, ada juga
yang menjadikan nilai orientasi ini bersifat kontinu / tidak diskrit.
Fined-grained sentiment analysis -
kategori kedua ini yang sedang Naik Daun sekarang. Maksudnya adalah para
researcher sebagian besar fokus pada jenis ini. Obyek yang ingin diklasifikasi
bukan berada pada level dokumen melainkan sebuah kalimat pada suatu dokumen.
Berikut dibawah ini merupakan tahapan
dalam pembuatan sentiment analyst menggunakan Bahasa pemrograman python.
1. Pada
pembuatan program kali ini memakai python versi 3.6.4
2. Berikut
merupakan listing program nya.
import os
import sys
import time
import json
import requests
import argparse
import lxml.html
import re
from textblob import TextBlob
from lxml.cssselect import CSSSelector
YOUTUBE_COMMENTS_URL =
'https://www.youtube.com/watch?v={youtube_id}'
YOUTUBE_COMMENTS_AJAX_URL =
'https://www.youtube.com/comment_ajax'
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; WOW64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36'
np = 0
nn = 0
n = 0
def clean_text(text_sel):
return '
'.join(re.sub("(@[A-Za-z0-9]+)|([^0-9A-Za-z \t])|(\w+:\/\/\S+)",
" ", text_sel).split())
def find_value(html, key, num_chars=2):
pos_begin
= html.find(key) + len(key) + num_chars
pos_end =
html.find('"', pos_begin)
return
html[pos_begin: pos_end]
def extract_comments(html):
global
np, n, nn
tree =
lxml.html.fromstring(html)
item_sel
= CSSSelector('.comment-item')
text_sel
= CSSSelector('.comment-text-content')
time_sel
= CSSSelector('.time')
author_sel = CSSSelector('.user-name')
for item
in item_sel(tree):
analysis = TextBlob(clean_text(text_sel(item)[0].text_content()))
# set
sentiment
if
analysis.sentiment.polarity > 0:
result = 'positive'
np += 1
elif analysis.sentiment.polarity == 0:
result = 'neutral'
n
+= 1
else:
result = 'negative'
nn += 1
yield
{'cid': item.get('data-cid'),
'text': text_sel(item)[0].text_content(),
'time': time_sel(item)[0].text_content().strip(),
'author': author_sel(item)[0].text_content(),
'result': result}
def extract_reply_cids(html):
tree =
lxml.html.fromstring(html)
sel =
CSSSelector('.comment-replies-header > .load-comments')
return
[i.get('data-cid') for i in sel(tree)]
def ajax_request(session, url, params, data,
retries=10, sleep=20):
for _ in
range(retries):
response
= session.post(url, params=params, data=data)
if
response.status_code == 200:
response_dict = json.loads(response.text)
return response_dict.get('page_token', None),
response_dict['html_content']
else:
time.sleep(sleep)
def download_comments(youtube_id, sleep=1):
session =
requests.Session()
session.headers['User-Agent'] = USER_AGENT
# Get
Youtube page with initial comments
response
= session.get(YOUTUBE_COMMENTS_URL.format(youtube_id=youtube_id))
html =
response.text
reply_cids = extract_reply_cids(html)
ret_cids
= []
for
comment in extract_comments(html):
ret_cids.append(comment['cid'])
yield
comment
page_token = find_value(html, 'data-token')
session_token = find_value(html, 'XSRF_TOKEN', 4)
first_iteration = True
# Get
remaining comments (the same as pressing the 'Show more' button)
while
page_token:
data =
{'video_id': youtube_id,
'session_token': session_token}
params = {'action_load_comments': 1,
'order_by_time': True,
'filter': youtube_id}
if
first_iteration:
params['order_menu'] = True
else:
data['page_token'] = page_token
response = ajax_request(session, YOUTUBE_COMMENTS_AJAX_URL, params,
data)
if
not response:
break
page_token, html = response
reply_cids += extract_reply_cids(html)
for
comment in extract_comments(html):
if comment['cid'] not in ret_cids:
ret_cids.append(comment['cid'])
yield comment
first_iteration = False
time.sleep(sleep)
# Get
replies (the same as pressing the 'View all X replies' link)
for cid
in reply_cids:
data
= {'comment_id': cid,
'video_id': youtube_id,
'can_reply': 1,
'session_token': session_token}
params = {'action_load_replies': 1,
'order_by_time': True,
'filter': youtube_id,
'tab': 'inbox'}
response = ajax_request(session, YOUTUBE_COMMENTS_AJAX_URL, params,
data)
if
not response:
break
_,
html = response
for
comment in extract_comments(html):
if comment['cid'] not in ret_cids:
ret_cids.append(comment['cid'])
yield comment
time.sleep(sleep)
def main(argv):
global
np, n, nn
parser =
argparse.ArgumentParser(add_help=False, description=('Download Youtube comments
without using the Youtube API'))
parser.add_argument('--help', '-h', action='help',
default=argparse.SUPPRESS, help='Show this help message and exit')
parser.add_argument('--youtubeid', '-y', help='ID of Youtube video for
which to download the comments')
parser.add_argument('--output', '-o', help='Output filename (output
format is line delimited JSON)')
parser.add_argument('--limit', '-l', type=int, help='Limit the number of
comments')
try:
args
= parser.parse_args(argv)
youtube_id = args.youtubeid
output = args.output
limit
= args.limit
if
not youtube_id or not output:
parser.print_usage()
raise ValueError('you need to specify a Youtube ID and an output
filename')
print('Downloading Youtube comments for video:', youtube_id)
count
= 0
with
open(output, 'w') as fp:
for comment in download_comments(youtube_id):
print(json.dumps(comment), file=fp)
count += 1
sys.stdout.write('Downloaded %d comment(s)\r' % count)
sys.stdout.flush()
if limit and count >= limit:
break
print('\n\nPositive: ', float(np/(np+n+nn)*100), '%')
print('Negative:
', float(nn/(np+n+nn)*100), '%')
print('Neutral: ', float(n/(np+n+nn)*100), '%')
print('\nDone!')
except
Exception as e:
print('Error:', str(e))
sys.exit(1)
if __name__ == "__main__":
main(sys.argv[1:])
3. Pastikan
sudah menginstall packages untuk program diatas.
a. pip
install requests
b. pip
install lxml
c. pip
install cssselect
d. pip
install textblob
4. Listing
program dibawah ini digunakan untuk mendeklarasikan beberapa url yang akan
diakses kedalam program dan beberapa variable untuk menampung nilai – nilai dalam
program.
YOUTUBE_COMMENTS_URL
= 'https://www.youtube.com/watch?v={youtube_id}'
YOUTUBE_COMMENTS_AJAX_URL
= 'https://www.youtube.com/comment_ajax'
USER_AGENT
= 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/48.0.2564.116 Safari/537.36'
np = 0
#persentase positif
nn = 0 #persentase
negatif
n = 0 #persentase
netral
5. def
extract_comments(html), berfungsi untuk mengambil data-data
komentar seperti penulis, waktu, dan komentar itu sendiri berdasarkan response
(html). Pada fungsi ini juga ditentukan apkah komentar itu positif, nagatif,
atau netral dengan TextBlob.
6.
def
extract_reply_cids(html), hampir sama dengan fungsi
sebelumnya hanya mengambil id reply
7.
def
download_comments(youtube_id, sleep=1), berfungsi untuk membuat
request session ke alamat URL youtube dan setelah mendapat response, response
tersebut dikirim ke fungsi extract_comments
8.
def
main(argv), fungsi yang pertama kali dijalankan dengan beberapa argument,
yaitu –youtubeid untuk meletakkan id youtube, --output untuk meletakkan
komentar kedalam file, --limit untuk membatasi komentar yang didownload. Pada
fungsi ini akan dijalankan fungsi download_comments
yang nilai baliknya akan dimasukkan kedalam file yang telah didefinisikan pada
saat menjalankan program ini (contoh: --output analisa.txt) , kemudian
menghitung persentase komentar positif, negative, dan netral.
Hasil
Dengan
contoh video https://www.youtube.com/watch?v=sRBsJNdK1t0
Sumber :
https://www.geeksforgeeks.org/twitter-sentiment-analysis-using-python/
https://github.com/egbertbouman/youtube-comment-downloader
http://alfan-farizki.blogspot.co.id/2011/01/apa-itu-sentiment-analysis-opinion.html