HSEOM GeckoHSEOM
Instagram

흑섬 TECH 블로그 - 데이터 기반 브리딩 기술

레오파드게코 브리딩에 데이터 분석과 AI 기술을 접목합니다. Python, NumPy를 활용한 체중 관리, 성장 추이 분석, 환경 데이터 시각화 등 실무에서 직접 사용하는 기술을 일반인도 이해하기 쉽게 설명합니다.

주요 카테고리

Play 카테고리

흑섬 TECH 블로그의 Play 카테고리입니다.

6개의 글이 있습니다.

[소셜 미디어 트렌드 3편] YouTube API로 댓글 523건 수집하고 감성 분석까지

Google Cloud Console에서 API 키를 발급받고, YouTube Data API v3으로 댓글을 수집합니다. 키워드 검색 → 영상 10개 → 댓글 523건 수집 → 1편 감성 분석 모델 적용까지, 실제 데이터 파이프라인을 만드는 과정입니다.

카테고리: Play

작성일: 2026-03-15T18:00:00

예상 읽기 시간: 14

Back to Tech
Play·14min read·

[소셜 미디어 트렌드 3편] YouTube API로 댓글 523건 수집하고 감성 분석까지

Google Cloud Console에서 API 키를 발급받고, YouTube Data API v3으로 댓글을 수집합니다. 키워드 검색 → 영상 10개 → 댓글 523건 수집 → 1편 감성 분석 모델 적용까지, 실제 데이터 파이프라인을 만드는 과정입니다.

시작하며 — 이제 진짜 데이터를 모을 차례

1편에서 감성 분석 모델을 만들었고, 2편에서 텍스트 EDA로 데이터 특성을 확인했습니다.
그런데 지금까지 쓴 데이터는 전부 NSMC(네이버 영화 리뷰) — 누군가 만들어놓은 공개 데이터셋이었죠.

이번 3편에서는 직접 데이터를 수집합니다.
YouTube Data API v3을 사용해서 키워드로 영상을 검색하고, 댓글을 수집하고,
1편에서 만든 모델로 감성 분석까지 적용해봅니다.


전체 흐름 — API 키부터 감성 분석까지

3편 전체 흐름도 — API 키 발급 → 영상 검색 → 댓글 수집 → 전처리 → 감성 분석

5단계로 진행됩니다. API 키 발급 → 영상 검색 → 댓글 수집 → 데이터 정리 → 감성 분석.
핵심은 API 두 개만 이해하면 됩니다.

  • search().list(): 키워드로 영상 검색 (100 유닛/회)
  • commentThreads().list(): 영상 댓글 조회 (1 유닛/회)

Step 1 — Google Cloud Console에서 API 키 발급

Google Cloud Console API 키 발급 5단계 가이드

구글 계정만 있으면 5분이면 발급됩니다.

  1. Google Cloud Console 접속 (console.cloud.google.com)
  2. 새 프로젝트 생성 — 이름은 아무거나 (예: youtube-comments)
  3. YouTube Data API v3 활성화 — API 및 서비스 → 라이브러리 → 검색
  4. 사용자 인증 정보 → API 키 만들기
  5. 키 복사 → 코드에서 사용
API 키는 절대 공개 저장소에 올리면 안 됩니다.
.env 파일이나 환경변수로 숨겨두세요.
할당량 초과되면 429 에러가 나옵니다.

Step 2 — API 클라이언트 생성 + 영상 검색

from googleapiclient.discovery import build
import pandas as pd
import time

youtube = build('youtube', 'v3', developerKey=API_KEY)
print("YouTube API 클라이언트 생성 완료!")
Jupyter 실행 결과 보기 — API 클라이언트 생성
YouTube API 클라이언트 생성 완료 — API Key: AIzaSyAnUp...

이제 이 클라이언트로 키워드를 넣어서 영상을 검색합니다.

def search_videos(query, max_results=10):
    request = youtube.search().list(
        q=query,
        type='video',
        part='snippet',
        maxResults=max_results,
        order='relevance',
        relevanceLanguage='ko'
    )
    response = request.execute()

    videos = []
    for item in response['items']:
        videos.append({
            'video_id': item['id']['videoId'],
            'title': item['snippet']['title'],
            'channel': item['snippet']['channelTitle'],
            'published': item['snippet']['publishedAt'][:10],
        })
    return videos

query = "파이썬 머신러닝"
videos = search_videos(query, max_results=10)
Jupyter 실행 결과 보기 — 영상 검색 결과
파이썬 머신러닝 검색 결과 — 10개 영상 목록

"파이썬 머신러닝"으로 검색하니 10개 영상이 나왔습니다.
search().list() 한번에 100 유닛이 소모됩니다. 일일 10,000 유닛이니까 하루에 100번 검색할 수 있는 셈이죠.


Step 3 — 댓글 수집 (페이지네이션)

댓글 수집 코드 흐름도 — build → search → for loop → commentThreads → nextPageToken → DataFrame

YouTube API는 한번에 최대 100개 댓글만 반환합니다.
댓글이 100개 넘는 영상이면 nextPageToken으로 다음 페이지를 반복 요청해야 합니다.

def get_comments(video_id, max_comments=100):
    comments = []
    next_token = None

    while len(comments) < max_comments:
        request = youtube.commentThreads().list(
            videoId=video_id,
            part='snippet',
            maxResults=min(100, max_comments - len(comments)),
            textFormat='plainText',
            order='relevance',
            pageToken=next_token
        )
        try:
            response = request.execute()
        except Exception as e:
            print(f"  Error: {e}")
            break

        for item in response['items']:
            snippet = item['snippet']['topLevelComment']['snippet']
            comments.append({
                'video_id': video_id,
                'author': snippet['authorDisplayName'],
                'comment': snippet['textDisplay'],
                'likes': snippet['likeCount'],
                'date': snippet['publishedAt'][:10],
            })

        next_token = response.get('nextPageToken')
        if not next_token:
            break

    return comments
Jupyter 실행 결과 보기 — 단일 영상 댓글 테스트
첫 번째 영상에서 댓글 수집 테스트 — 샘플 5개 출력

한 영상으로 테스트해보면 댓글이 잘 수집됩니다.
이제 10개 영상 전체를 반복합니다.

all_comments = []

for i, v in enumerate(videos, 1):
    print(f"  [{i}/{len(videos)}] {v['title'][:40]}...", end=" ")
    comments = get_comments(v['video_id'], max_comments=200)
    all_comments.extend(comments)
    print(f"→ {len(comments)} comments")
    time.sleep(1)  # API 할당량 보호

df = pd.DataFrame(all_comments)
Jupyter 실행 결과 보기 — 전체 영상 댓글 수집
10개 영상에서 총 523건 댓글 수집 — DataFrame 생성
time.sleep(1)을 넣은 이유는 할당량 보호입니다.
너무 빠르게 요청하면 할당량을 순식간에 소진하거나, 429(Too Many Requests) 에러가 날 수 있습니다.

Step 4 — 수집 데이터 확인 + CSV 저장

수집 데이터 테이블 구조 — video_id, author, comment, likes, date
print(f"Total comments: {len(df):,}")
print(f"Unique videos: {df['video_id'].nunique()}")
print(f"Avg comment length: {df['comment'].str.len().mean():.1f} chars")

df.to_csv('youtube_comments.csv', index=False, encoding='utf-8-sig')
Jupyter 실행 결과 보기
수집 결과 — 523건, 9영상, 505명, 평균 101.7자, CSV 저장

523건 수집, 영상 9개(댓글 비활성화 1개 제외), 작성자 505명.
재밌는 건 평균 댓글 길이가 101.7자라는 거예요. NSMC 영화 리뷰(평균 35자)보다 거의 3배 길죠.
YouTube 댓글은 한줄평보다 서술형이 많으니까 그런 것 같습니다.


Step 5 — 1편 감성 분석 모델 적용

드디어 1편에서 만든 모델을 실전에 적용합니다.
NSMC로 학습한 Logistic Regression(82.8%)을 YouTube 댓글에 바로 적용해봅니다.

# 1편 전처리 함수 + 모델 재학습
from konlpy.tag import Okt
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression

# NSMC 데이터로 모델 학습 (1편과 동일)
train = pd.read_csv('ratings_train.txt', sep='\t')
train = train.dropna(subset=['document'])
train['clean'] = train['document'].progress_apply(tokenize)

tfidf = TfidfVectorizer(max_features=10000)
X_train = tfidf.fit_transform(train['clean'])
lr = LogisticRegression(max_iter=1000)
lr.fit(X_train, train['label'])
Jupyter 실행 결과 보기 — 모델 학습
NSMC 모델 학습 완료 — LR Accuracy ~82.8%
# YouTube 댓글에 감성 분석 적용
df['clean'] = df['comment'].apply(tokenize)
X_comments = tfidf.transform(df['clean'])
df['sentiment'] = lr.predict(X_comments)
df['confidence'] = lr.predict_proba(X_comments).max(axis=1)

pos_count = (df['sentiment'] == 1).sum()
neg_count = (df['sentiment'] == 0).sum()
print(f"Positive: {pos_count:,} ({pos_count/len(df):.1%})")
print(f"Negative: {neg_count:,} ({neg_count/len(df):.1%})")
Jupyter 실행 결과 보기 — 감성 분석 결과
감성 분석 결과 — Positive 364건(69.6%), Negative 159건(30.4%), 평균 신뢰도 71.9%

결과를 보면 긍정 69.6%, 부정 30.4%입니다.
"파이썬 머신러닝" 관련 영상이다 보니 "감사합니다", "유익해요" 같은 긍정 댓글이 많은 건 자연스럽습니다.
평균 신뢰도는 71.9%로, NSMC 영화 리뷰로 학습한 모델이 YouTube 댓글에서도 어느 정도 작동한다는 걸 확인했습니다.

신뢰도 71.9%가 낮은 건 아닌가?
NSMC는 "영화 리뷰" 데이터이고, YouTube 댓글은 주제와 문체가 다릅니다.
도메인이 다르면 성능이 떨어지는 건 당연합니다. 실무에서는 YouTube 댓글로 다시 학습(Fine-tuning)하는 과정이 필요합니다.

API 할당량 관리 — 무료로 얼마나 할 수 있나

API 할당량 관리 — 일일 10,000 유닛, search 100유닛, commentThreads 1유닛

YouTube Data API v3은 일일 10,000 유닛이 무료입니다.
가장 비싼 건 search().list() — 1회에 100 유닛.
반면 commentThreads().list()는 1회에 1 유닛이라 거의 부담 없습니다.

오늘 실습에서 쓴 할당량을 계산해보면:
search 1회(100) + commentThreads 약 50회(50) = 약 150 유닛.
하루에 이런 작업을 66번은 할 수 있는 셈이니, 개인 프로젝트에는 충분합니다.


정리 — 3편에서 한 것들

3편 정리 — 5단계 흐름 + 시리즈 진행 상태
  1. API 키 발급: Google Cloud Console에서 YouTube Data API v3 활성화
  2. 영상 검색: search().list()로 "파이썬 머신러닝" 관련 영상 10개 탐색
  3. 댓글 수집: commentThreads().list() + 페이지네이션으로 523건 수집
  4. 데이터 정리: DataFrame 변환 + CSV 저장 (평균 101.7자, 505명)
  5. 감성 분석: 1편 모델 적용 → 긍정 69.6%, 부정 30.4% (신뢰도 71.9%)

다음 4편에서는 이 데이터를 LDA 토픽 모델링으로 주제별로 분류하고,
Streamlit 대시보드로 시각화해서 최종 결과물을 만듭니다.

#YouTube API#데이터수집#감성분석#google-api-python-client#python