지인이 대학원 논문을 써야 하는데 유튜브 댓글을 수집해야한다고 해서 호기롭게 해준다고 해놓고 꽤나 헤맸다ㅋ
처음에 google colab으로 진행하다가 계속되는 이슈에 pycharm 설치... 어디서부터 손을 대야 할 지 몰라서 anaconda 설치 후 jupyter 로 진행했다.
유튜브 내 코드가 수시로 바껴서 댓글수집할 때 애를 좀 먹었다. 어제 됐던 코드가 안된다던지 하는 경우가 발생했다. 유튜브 댓글 크롤링 시에는 웹 상 코드도 틈틈히 봐주면서 수정해야할 것 같다.
##############################luna##############################
# matplotlib의 inline 백엔드를 활성화하여 Jupyter notebook 내에서 그래프를 바로 볼 수 있게 함
%matplotlib inline
# 필요한 라이브러리들을 임포트
from selenium import webdriver
import time
from bs4 import BeautifulSoup
import pandas as pd
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
# 브라우저를 GUI 없이 실행하는 headless Chrome 설정
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
# 위에서 설정한 옵션으로 Chrome WebDriver 인스턴스 생성
driver = webdriver.Chrome(options=options)
# 분석할 YouTube 동영상 URL들을 리스트로 정의
urls = [
"https://youtu.be/i6K8i9BMr14?si=tbzezCAiHguzpzyb",
# 나머지 URL들...
]
# 모든 동영상의 댓글을 저장할 빈 리스트 생성
all_comments = []
# 각 동영상 URL에 대해 반복하여 댓글 수집
for url in urls:
# 해당 URL의 웹 페이지 로드
driver.get(url)
# 암묵적 대기
driver.implicitly_wait(3)
# 페이지 맨 아래까지 스크롤하여 댓글 섹션 로딩
last_height = driver.execute_script("return document.documentElement.scrollHeight")
while True:
driver.execute_script("window.scrollTo(0, document.documentElement.scrollHeight);")
time.sleep(2) # 필요에 따라 대기 시간 조정
new_height = driver.execute_script("return document.documentElement.scrollHeight")
if new_height == last_height:
try:
# '더 보기' 버튼이 있으면 클릭
dismiss_button = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, '#dismiss-button > a')))
dismiss_button.click()
except:
break
last_height = new_height
# 스크롤 후의 HTML 소스 가져오기
html_source = driver.page_source
# BeautifulSoup으로 HTML 파싱
soup = BeautifulSoup(html_source, 'html.parser')
# 댓글 섹션에서 댓글 추출
comments_section = soup.find_all('ytd-comment-thread-renderer')
for comment in comments_section:
comment_text = comment.find("yt-attributed-string", id="content-text").text.strip()
all_comments.append(comment_text)
# 브라우저 종료
driver.quit()
### 특수문자 제거하기 ###
import re
compile = re.compile("[^ ㄱ-ㅣ가-힣]+")
for i in range(len(all_comments)):
a = compile.sub("", all_comments[i])
all_comments[i] = a
### 문장 분석 ###
from konlpy.tag import Okt
okt = Okt()
result = [okt.nouns(i) for i in all_comments] # 댓글에서 명사만 추출
final_result = [r for i in result for r in i]
### 불용어 제거하기 ###
stop_word = ["더", "킹", "것", "때", "년", "왜", "브레이", "그", "좀", "거", "이"]
final_result = [i for i in final_result if i not in stop_word]
# 불용어 제거 결과 출력
print('불용어 제거', final_result)
## 한국어 top 30 단어 출력 ##
korean = pd.Series(final_result).value_counts().head(30)
print("top 30")
print(korean)
# 댓글 내용을 포함하는 DataFrame 생성
youtube_df = pd.DataFrame(final_result, columns=['댓글 내용'])
# 워드 클라우드 생성을 위한 텍스트 데이터 준비
text = " ".join(li for li in youtube_df['댓글 내용'].astype
# matplotlib.pyplot을 plt라는 이름으로 임포트하여 시각화 기능을 사용할 수 있게 함
import matplotlib.pyplot as plt
# wordcloud 라이브러리에서 WordCloud, STOPWORDS, ImageColorGenerator를 임포트
from wordcloud import WordCloud, STOPWORDS, ImageColorGenerator
# 워드클라우드에 사용할 한글 폰트 경로 설정
fontpath = './NanumBarunGothic.ttf'
# PIL 라이브러리에서 Image 모듈을 임포트하여 이미지 처리 기능을 사용할 수 있게 함
from PIL import Image
# numpy를 np라는 이름으로 임포트하여 배열 관련 연산을 수행할 수 있게 함
import numpy as np
# 마스크 이미지 로드 및 색상 반전 과정
# 마스크로 사용할 이미지 파일을 열어 Image 객체로 생성
mask_image = Image.open("./kang_freeze_fi.png")
# Image 객체를 numpy 배열로 변환하고, np.invert 함수를 이용해 픽셀 값의 색상을 반전시킴
mask_image = np.invert(np.array(mask_image))
# 워드클라우드 객체 생성
wordcloud = WordCloud(
background_color = 'black', # 배경 색상 설정
width = 1000, height = 700, # 워드클라우드 이미지의 너비와 높이 설정
font_path = fontpath, # 한글 폰트 경로 설정
mask = mask_image # 워드클라우드 모양을 결정할 마스크 이미지 설정
).generate(text) # 워드클라우드를 생성할 텍스트 데이터
# matplotlib의 subplots 함수를 이용하여 그림과 축을 생성, figsize로 그림의 크기를 지정
plt.subplots(figsize = (25, 15))
plt.axis('off') # 축을 표시하지 않음
plt.imshow(wordcloud, interpolation = 'bilinear') # 워드클라우드 이미지를 화면에 표시, interpolation은 이미지가 부드럽게 보이도록 함
plt.show() # 생성한 워드클라우드를 화면에 출력