언빌리버블티
[KDT] YouTube API를 활용하여 영상 데이터 리스트업하기 (1) YouTube API 호출하기 본문
[KDT] YouTube API를 활용하여 영상 데이터 리스트업하기 (1) YouTube API 호출하기
나는 정은 2022. 10. 4. 03:14멋쟁이 사자처럼 AI스쿨 7기
제 1회 미니 프로젝트 회고 - 1 (2022-09-26 ~ 2022-10-03)
YouTube API와 Pandas 라이브러리를 활용한 데이터 scrapping

유튜브 API를 활용하여 Youtube 채널 영상 데이터 수집
미니 프로젝트 회고
유튜브라는 플랫폼을 주제로 정하고 데이터 스크래핑 과제를 수행하였다 !
Google Developers의 " YouTube Data API v3 "를 통해 유튜브 채널의 다양한 데이터를 수집하였다.
Search, CommentThreads , PlaylistItems 이 세가지 REST API를 사용하여 다양한 분석 과제를 수행할 수 있었다 !
- 채널 아이디 & 채널에 업로드된 영상 Id list 수집
- 채널 별로 일정 기간 조회수, 좋아요 수, 댓글 수의 변화 분석
- 영상 별 댓글 데이터 수집 및 주요 키워드 시각화
- 조회수가 많이 나오는 영상의 타이틀 키워드 시각화
구글 API 발급법은 아래 링크를 참고하였다 !
OAuth 2.0 인증 + YouTube Data API v3 의 API KEY를 발급 받아야한다 !
[오픈소스 리뷰기] YouTube API 이용하기(1) - API 키 발급하기
오프소스 리뷰 : 슬기로운 오픈소스 사용법 리뷰해드립니다! #3 YouTube API 이용하기(1) - API 키 발급하기 안녕하세요. 디노랩스입니다 :) 여러분도 유튜브 많이 보시나요? YouTube는 현재 비디오 컨텐
www.dinolabs.ai
YouTube Data API 같은 경우 할당량 이라는 게 있기 때문에 주의해서 호출해야한다.
나는 하루에 10,000 쿼리를 사용할 수 있었다.
작업마다 다른 쿼리를 소비하기 때문에 할당량 체크 필수 !
시작하기 | YouTube Data API | Google Developers
시작하기 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 소개 이 문서는 YouTube와 상호작용할 수 있는 애플리케이션을 개발하려는 개발자를 위해 작성되었
developers.google.com
Code
유튜브 채널의 영상을 수집하기 위해서는 Video Id라는 값이 필요했다.
이는 YouTube Data API에서 제공하는 다양한 리소스들을 이용해서 구할 수 있었다 !
채널 Id 값 또한 url 리소스 변환 사이트를 이용해야하나 싶었는데 다행히도 API 호출을 통해 수집해낼 수 있었다 !
API 호출 방식을 활용하여 우리팀은 총 2가지 종류의 데이터를 수집했다.
유튜브 영상 목록과 영상 데이터를 수집하는 코드
1) channel_name을 입력 받는다.
2) Search API를 호출하여 Channel Id를 가져온다.
3) PlaylistItems API를 통해 반복문으로 Json 데이터를 순회하면서 Video Id 값들을 수집하고 저장한다.
3-1 ) nextPageToken 값을 통해 scroll을 더 이상 할 수 없을 때까지 video 정보가 저장된 Json 배열을 수집한다.
4) 반환된 Video List를 반복문을 통해 순회하면서 Video Id만 추출하여 리스트에 저장한다.
5) Video Id List를 하나씩 순회하면서 video에 저장된 정보를 찾아 DataFrame에 담는다.
6) 저장된 df_video 데이터 프레임을 csv 파일로 저장한다.
함수 구조
* get_channel_info(채널명, API_KEY, 파일명): 유튜브 채널의 영상 목록과 정보 df 반환
* get_video_id(채널명, API_KEY): 유튜브 video Id 목록 수집
* get_channel(채널명, API_KEY) : 채널 아이디 수집
* get_scroll(채널Id, API_KEY) : 다음 페이지를 탐색하여 영상 추가
* save_file(name, type, df_video_info) : 저장된 영상 목록 df csv파일로 저장
하나의 유튜브 영상에 달린 댓글에 대한 데이터를 수집하는 코드
1) Video name과 Id를 입력받는다.
2) CommentThreads API를 호출하여 각 비디오에 대한 댓글을 수집한다.
3) 수집한 댓글들의 Json 배열을 순회하면서 댓글과 대댓글 데이터를 수집한다.
3-1 ) nextPageToken 값을 통해 scroll을 더 이상 할 수 없을 때까지 데이터를 수집한다.
4) 수집한 댓글 목록을 DataFrame에 담는다.
5) 저장된 df_comment 데이터 프레임을 csv 파일로 저장한다.
함수 구조
* get_comments(video_id, video_name ,API_KEY) : 모든 페이지의 댓글과 대댓글 수집
* save_file(video_name, "comment" ,comment_df) : 수집한 댓글 데이터 csv 파일로 저장
0. 라이브러리 로드
# 필요한 라이브러리 import
import numpy as np
import pandas as pd
from datetime import datetime as dt
from tqdm import tqdm
import time
from googleapiclient.discovery import build
import os
import warnings # 경고창 무시
warnings.filterwarnings('ignore')
Google api client 라이브러리 설치
!pip install google-api-python-client
- pandas : 수집한 데이터들을 Table 형태로 저장하기 위한 라이브러리
- build : Google API를 호출하기 위한 객체를 지원하는 라이브러리
API 요청 쿼리값 세팅
# 쿼리값 세팅
API_KEY = "*" # 개인 API_KEY
DEVELOPER_KEY = API_KEY
YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"
youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=DEVELOPER_KEY)
youtube 라는 Google API 객체를 생성하고 api에서 제공하는 검색 기능을 활용하기 위해 search.list.method를 사용
- q : 검색어
- order : 정렬 방식
- maxResults : 최대 호출 개수
검색한 채널의 Id값을 반환
search_response = youtube.search().list(
q = channel_name,
order = "relevance",
part = "snippet",
maxResults = 50
).execute()
channel_Id = search_response['items'][0]['id']['channelId']
return channel_Id
hoWQWbMFodc
I. 채널 내 영상 리스트 데이터 수집
playlists에 저장된 video 목록의 josn 쿼리 수집
- 수집한 채널 아이디 값을 가지고 playlist 내 video 쿼리를 수집한다.
- 재생 목록을 돌면서 영상 목록을 수집한다.
- nextPageToken을 가지고 다음 페이지를 더 이상 불러오지 못할 때까지 호출한다.
- 재생 목록을 돌면서 영상 목록을 수집한다.
try :
res = youtube.channels().list(id=channel_Id, part='contentDetails').execute()
# 플레이리스트 가져오기
playlist_id = res['items'][0]['contentDetails']['relatedPlaylists']['uploads']
next_page = None
# 영상 개수가 1000이 넘지 않도록 수집
while len(video_list) < 1000:
res = youtube.playlistItems().list(playlistId=playlist_id,part='snippet',maxResults=50,pageToken=next_page).execute()
video_list += res['items']
next_page = res.get('nextPageToken')
if next_page is None :
break
except:
print('API 호출 한도 초과') # API 할당량 초과 시
video_list
- next_page에 대한 토큰 값이 반환되지 않는다면 데이터 수집을 중단한다.
반환되는 JSON 쿼리의 key_value값은 공식 문서에 자세히 나와있다 !
PlaylistItems | YouTube Data API | Google Developers
PlaylistItems 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. playlistItem 리소스는 재생목록에 포함된 동영상과 같은 다른 리소스를 식별합니다. 또한 playlistItem
developers.google.com
{
"kind": "youtube#playlistItem",
"etag": etag,
"id": string,
"snippet": {
...
"contentDetails": {
"videoId": string,
...
- 다시보니 여기에 videoId가 있다..
수집한 Video Json 쿼리에서 Video Id만 수집
channel_Id = get_channel(channel_name, api_key)
video_list = scroll(channel_Id)
df_video = pd.DataFrame()
for item in video_list:
item_dict = {}
item_dict['title'] = item['snippet']['title']
item_dict['video_id'] = item['snippet']['resourceId']['videoId']
df_video = df_video.append(item_dict , ignore_index = True)
df_video
- Json 쿼리 여러 개가 저장되어있는 video_list에서 쿼리 하나를 뽑은 뒤 Video Id를 찾아서 수집한다.
- DataFrame에 저장하고 Video_Id list 를 반환한다.
각 채널의 Video 목록 데이터 수집하기.
df_video_info = pd.DataFrame()
df_url = get_video_id(channel, api_key)
url_list = df_url['video_id'].to_list()
try :
for video_id in url_list:
item_list = {}
res = youtube.videos().list(id = video_id, part='snippet,contentDetails,statistics').execute()
if res['items']:
item_list['video_id'] = video_id
item_list['title'] = res['items'][0]['snippet']['title']
item_list['date'] = res['items'][0]['snippet']['publishedAt'].split('T')[0]
# 수치형 자료 가져오기 - NaN값은 0으로 간주
item_list['view'] = int(res['items'][0]['statistics']['viewCount']) if 'viewCount' in res['items'][0]['statistics'] else 0
item_list['likecnt'] = int(res['items'][0]['statistics']['likeCount']) if 'likeCount' in res['items'][0]['statistics'] else 0
item_list['comment'] = int(res['items'][0]['statistics']['commentCount']) if 'commentCount' in res['items'][0]['statistics'] else 0
df_video_info = df_video_info.append(item_list, ignore_index = True).reset_index(drop=True)
df_video_info['channel_name'] = channel_name
except:
print('DataFrame 생성 에러')
df_video_info
- columns 가 ['비디오ID', '영상 제목', '업로드 날짜', '조회수', '좋아요 수', '댓글 수'] 인 DataFrame을 구성하였다.
- Video를 search하는 API를 호출하여 각 영상 Id를 통해 영상에 대한 정보들을 수집해왔다.
- publishedAt 데이터의 경우 T를 기준으로 쪼개주고 그 앞의 값까지만 수집했다.
- Video를 search하는 API를 호출하여 각 영상 Id를 통해 영상에 대한 정보들을 수집해왔다.
- 각 채널 별로 데이터를 비교하기 위해 Channel Name도 함께 추가해준 뒤 df를 반환한다.
II. 특정한 영상에 달린 댓글 데이터 수집
CommentThreads API 를 활용한 유튜브 댓글 수집
comments = []
comment_list_response = youtube.commentThreads().list(
videoId = video_id,
order = 'relevance',
part = 'snippet,replies',
maxResults = 100
).execute()
- 먼저 수집할 댓글을 저장할 List 타입의 Commnets를 생성한다.
- build를 통해 google API 객체를 생성
- reponse 에 전달받은 데이터가 저장된다.
- build를 통해 google API 객체를 생성
while comment_list_response:
for item in comment_list_response['items']:
comment = item['snippet']['topLevelComment']['snippet']
comments.append([comment['textDisplay'], comment['authorDisplayName'], comment['publishedAt'], comment['likeCount']])
if item['snippet']['totalReplyCount'] > 0:
for reply_item in item['replies']['comments']:
reply = reply_item['snippet']
comments.append([reply['textDisplay'], reply['authorDisplayName'], reply['publishedAt'], reply['likeCount']])
if 'nextPageToken' in comment_list_response:
comment_list_response = youtube.commentThreads().list(
videoId = video_id,
order = 'relevance',
part = 'snippet,replies',
pageToken = comment_list_response['nextPageToken'],
maxResults = 100
).execute()
else:
break
- 반복문을 순회하면서 댓글을 저장하고 API를 재호출하는 과정을 반복한다.
- 하나의 댓글에서 다음 4가지 정보를 수집한다.
- textDisplay: 댓글의 내용
- authorDisplayName: 댓글 작성자
- publishedAt: 댓글 작성 시간
- likeCount: 좋아요 수
- 하나의 댓글에서 다음 4가지 정보를 수집한다.
- 댓글에 대한 댓글 (reply)이 있는 경우 reply도 같이 수집
- 영상에서 가져올 댓글이 아직 남은 경우에 nextPageToken을 기반으로 API를 다시 호출
- 수집된 모든 댓글은 comments list에 저장된다.
III. 데이터 프레임 CSV 파일로 저장하기
today = dt.today().strftime("%Y%m%d")
file_name = f'Youtube_{type_}_{name}_{today}'
- 언제 불러온 데이터인지 표시하기 위해 datetime 라이브러리의 today() 함수를 사용
- strftrime()으로 문자열 포매팅
- comment 데이터인지 video 데이터인지 구분해서 file_name을 구성했다.
버전 관리
version = 0
while os.path.isfile(f'./{file_name}_v{version}.csv'):
version += 1
df.to_csv(f'./{file_name}_v{version}.csv', index=False)
- 저장한 csv 파일이 겹치지 않도록 하기 위해 코드를 추가해주었다.
- 파일이 디렉토리에 존재하면 버전을 갱신해준다.
Result
1) 영상 info 데이터 수집
channel = '동빈나'
# 파일로 저장할 때 쓰일 채널명
name = "동빈나"
df_channel_info = get_channel_info(channel, API_KEY, name)
df_channel_info

- 유튜브 동빈나 채널의 영상 제목, 조회수, 좋아요 수, 댓글 수를 수집
- 데이터 프레임으로 반환한 결과를 출력하였다.
- 조코딩 유튜브 채널 데이터도 수집해보았다 !
2) 영상 댓글 데이터 수집
- 댓글 수가 가장 많은 영상을 찾는다.
df = df.sort_values(by=["comment"], ignore_index=True, ascending = False)
video_id = df['video_id'][0]
C언어 기초 프로그래밍 강좌 1강 - Hello World (C Programmin... --- 790개
get_comments(video_id, video_name ,API_KEY)
- 제일 인기가 많은 영상의 댓글들을 전부 수집해보았다.
3) 가장 많이 본 영상 TOP 10
- 수집한 데이터 중 조코딩 채널에서 가장 조회수가 높은 영상 TOP 10을 알아보자
df_channel_info.sort_values(by=["view","likecnt",'comment'],ascending=False, ignore_index = True)[:10]

쇼츠 영상의 인기가 대단했다.
https://www.youtube.com/shorts/cXB8rCW7lto 이 영상이 가장 인기가 많았다는 것을 간단히 알아볼 수 있다 !
Reference
Python을 이용한 이용한 유튜브 (YouTube) 댓글 수집
1. YouTube Data API YouTubue 댓글 수집에는 Google에서 제공하는 YouTube Data API를 이용하는 방법과 동영상이 게시된 HTML 문서에서 직접 데이터를 크롤링 (crawling)하는 방법이 있다. 그러나 크롤링 방식은..
untitledtblog.tistory.com
[Python] 유튜브 콘텐츠 크롤러 코드 Version 1.0
본 포스팅에서는 파이썬 기반 유튜브 콘텐츠 Scrpaer 코드를 공유합니다. 📝 목차 1. 주요 기능 2. 크롬 설치 3. 전체 코드 4. 패키지 설치 5. 코드 설명 1. 주요 기능 1) 유튜브 내 검색 결과의 콘텐
heytech.tistory.com
'Data Science > KDT' 카테고리의 다른 글
[KDT] 내 거친 성적과 불안한 공교육💦 : 대한민국 사교육 환경 변화와 원인 분석 (4) | 2022.10.27 |
---|---|
[KDT] 공공데이터를 활용한 서울시 대중교통 이용현황 분석 - (2) Seaborn과 matplotlib을 활용한 시각화 (0) | 2022.10.27 |
[KDT] 공공데이터를 활용한 서울시 대중교통 이용현황 분석 - (1) 데이터 수집 및 전처리 (0) | 2022.10.27 |
[KDT] YouTube API를 활용하여 수집한 데이터 분석하기 (2) KoNLPy 단어 형태소 추출 & WordCloud 시각화 (0) | 2022.10.05 |
[KDT] Python 웹 스크래핑으로 네이버 금융 개별종목 데이터 수집 (0) | 2022.09.29 |