오프소스 리뷰 : 슬기로운 오픈소스 사용법 리뷰해드립니다!
#4 YouTube API 이용하기(2) - API 키 활용하기

안녕하세요. 디노랩스입니다!
지난번 포스팅에서 유튜브 API 키를 발급받는 법을 알려드렸는데요.
오늘은 발급받은 API 키를 어떻게 활용하는지
- 검색결과 가져오기
- 재생목록 가져오기
- 재생목록 내 동영상 가져오기
- 동영상 정보 가져오기
- 댓글 가져오기
총 다섯가지 활용법을 리뷰해 드리겠습니다 :D
▽▼ 다시한번 보러가기 ▽▼
2021.11.03 - [BLOG/오픈소스 리뷰기] - [오픈소스 리뷰기] YouTube API 이용하기(1) - API 키 발급하기
02. API 키 활용하기
API를 활용하기 전에 먼저 아래의 pip 명령어를 이용해 Google api client 라이브러리를 설치하고 필요한 라이브러리를 import 합니다.
pip install google-api-python-clientfrom googleapiclient.discovery import build
from googleapiclient.errors import HttpError
from oauth2client.tools import argparser
(1) 검색결과 가져오기
먼저 유튜브 검색창에 "슈카월드"라는 검색어를 입력했을 때 나오는 결과들을 수집해보겠습니다.

DEVELOPER_KEY = '' # 유튜브 API 키값을 입력하세요
YOUTUBE_API_SERVICE_NAME = 'youtube'
YOUTUBE_API_VERSION = 'v3'youtube라는 Google API 객체를 생성한 뒤, api에서 제공하는 검색기능을 활용하기 위해 search.list method를 사용합니다.
list에 들어가는 중요 파라미터는 다음과 같습니다.
- q : 검색어
- order : 정렬방식
- maxResults : 최대 호출 개수
search.list method에 대한 자세한 설명은 아래 공식 레퍼런스에서 확인할 수 있습니다.
https://developers.google.com/youtube/v3/docs/search/list
Search: list | YouTube Data API | Google Developers
Search: list API 요청에 지정된 쿼리 매개변수와 일치하는 검색결과의 모음을 반환합니다. 기본적으로 검색결과의 집합은 쿼리 매개변수와 일치하는 video, channel, playlist 리소스를 식별하지만, 특정
developers.google.com
youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=DEVELOPER_KEY)
search_response = youtube.search().list(
    q = '슈카월드',
    order = 'relevance',
    part = 'snippet',
    maxResults = 50
).execute()search_response 변수를 출력하면 아래와 같이 JSON 형태의 결과를 확인할 수 있습니다.

검색결과 내에 있는 Title만을 가져오는 것은 아래와 같은 간단한 반복문 코드로 수행할 수 있습니다.
titles = []
for item in search_resoponse['items']:
    titles.append(item['snippet']['title'])
(2) 재생목록 가져오기
이번에는 "슈카월드" 채널에 있는 재생목록 리스트를 구해볼 건데요.

가장 먼저 채널마다 가지고 있는 고유의 ID를 구해야하는데 검색결과에서 호출한 JSON 구조를 활용하여 아래와 같이 추출할 수 있습니다.

channel_id = search_response['items'][0]['id']['channelId']이전에 search.list method를 사용한 것과 달리 이번에는 재생목록 리스트를 가져오기 위해 playlists.list method를 사용합니다.
method에 대한 자세한 설명은 아래 공식 레퍼런스에서 확인할 수 있습니다.
https://developers.google.com/youtube/v3/docs/playlists/list
Playlists: list | YouTube Data API | Google Developers
Playlists: list API 요청 매개변수와 일치하는 재생목록의 모음을 반환합니다. 예를 들어 인증된 사용자가 보유한 전체 재생목록을 검색하거나, 고유 ID를 통해 하나 또는 여러 개의 재생목록을 검색
developers.google.com
youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=DEVELOPER_KEY)
playlists = youtube.playlists().list(
    channelId = channel_id,
    part = 'snippet',
    maxResults = 20
).execute()
검색결과 데이터를 요청했을 때와 마찬가지로 JSON 형태의 데이터로 결과를 받는 것을 확인할 수 있으며 간단한 반복문을 통해 데이터프레임으로 저장할 수 있습니다.
import pandas as pd
df = pd.DataFrame()
for item in playlists['items']:
    item_dict = {}
    item_dict['playlist'] = item['snippet']['title']
    item_dict['playlist_id'] = item['id']
    df = df.append(item_dict, ignore_index = True)
(3) 재생목록 내 동영상 가져오기
채널에 있는 재생목록 리스트를 가져왔다면 이번에는 재생목록에 있는 동영상 리스트를 가져와볼게요!

이번에는 재생목록 내 동영상 리스트를 제공하는 playlistItems.list method를 사용합니다.
method에 대한 자세한 설명은 아래 공식 레퍼런스에서 확인할 수 있습니다.
https://developers.google.com/youtube/v3/docs/playlistItems/list
PlaylistItems: list | YouTube Data API | Google Developers
PlaylistItems: list API 요청 매개변수와 일치하는 재생목록 항목의 모음을 반환합니다. 지정된 재생목록의 모든 항목을 검색하거나 고유 ID를 통해 하나 또는 여러 개의 재생목록 항목을 검색할 수
developers.google.com
video_ids = []
video_titles = []
for id in df['playlist_id']:
    playlistitems_list_request = youtube.playlistItems().list(
        playlistId = id, # 재생목록의 id를 입력합니다
        part = 'snippet',
        maxResults = 50
    )
    while playlistitems_list_request:
        playlistitems_list_response = playlistitems_list_request.execute()
        for item in playlistitems_list_response['items']:
            title = item['snippet']['title']
            video_id = item['snippet']['resourceId']['videoId']
            
            video_titles.append(title)
            video_ids.append(video_id)
        
        playlistitems_list_request = youtube.playlistItems().list_next(
            playlistitems_list_request, playlistitems_list_response
        )
video_df = pd.DataFrame()
video_df['video_title'] = video_titles
video_df['video_id'] = video_ids
(4) 동영상 정보 가져오기
playlistItems method를 통해서 동영상 제목과 id를 가져왔지만 영상의 크기, 상태, 조회수, 댓글수와 같은 다양한 정보를 가져올 수는 없습니다.
이는 videos.list method를 통해 가져올 수 있습니다.
https://developers.google.com/youtube/v3/docs/videos/list
Videos: list | YouTube Data API | Google Developers
Videos: list API 요청 매개변수와 일치하는 동영상의 목록을 반환합니다. 지금 사용해 보거나 예를 참조하세요. 요청 HTTP 요청 GET https://www.googleapis.com/youtube/v3/videos 매개변수 아래 표는 이 쿼리가 지
developers.google.com
import re
titles = []         # 동영상 제목
ids = []            # 동영상 id
dates = []          # 동영상 업로드 날짜
category_ids = []   # 동영상 카테고리 id
views = []          # 조회 수
likes = []          # 좋아요 수
dislikes = []       # 싫어요 수
comments = []       # 댓글 수
hours = []          # 동영상 재생길이(시)
mins = []           # 동영상 재생길이(분)
secs = []           # 동영상 재생길이(초)
for i in range(len(video_df)):
    request = youtube.videos().list(
        id = video_df['video_id'][i], # 동영상 id를 입력합니다
        part = 'snippet,contentDetails,statistics'
    )
    response = request.execute()
    if response['items'] == []: # 동영상 정보가 없을 경우 '-'로 입력
        titles.append('-')
        ids.append('-')
        dates.append('-')
        category_ids.append('-')
        views.append('-')
        likes.append('-')
        dislikes.append('-')
        comments.append('-')
        hours.append('-')
        mins.append('-')
        secs.append('-')
    else:
        titles.append(response['items'][0]['snippet']['title'])
        ids.append(video_df['video_id'][i])
        dates.append(response['items'][0]['snippet']['publishedAt'].split('T')[0])
        category_ids.append(response['items'][0]['snippet']['categoryId'])
        views.append(response['items'][0]['statistics']['viewCount'])
        likes.append(response['items'][0]['statistics']['likeCount'])
        dislikes.append(response['items'][0]['statistics']['dislikeCount'])
        comments.append(response['items'][0]['statistics']['commentCount'])
        duration = re.findall(r'\d+', response['items'][0]['contentDetails']['duration'])
        if len(duration) == 3:
            hours.append(duration[0])
            mins.append(duration[1])
            secs.append(duration[2])
        elif len(duration) == 2:
            hours.append('-')
            mins.append(duration[0])
            secs.append(duration[1])
        else:
            hours.append('-')
            mins.append('-')
            secs.append(duration[0])
detail_df = pd.DataFrame([titles,ids,dates,category_ids,views,likes,dislikes,comments,hours,mins,secs]).T
detail_df.columns = ['title','id','date','category_id','view','like','dislike','comment','hour','min','sec']
이렇게 수집한 데이터를 간단한 전처리 후 조회수가 높은 Top 10 영상을 살펴보겠습니다.
detail_df = detail_df[detail_df['view'] != '-']
detail_df['view'] = detail_df['view'].astype(int)
top10_df = detail_df.sort_values(by='view', ascending=False).head(10)/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:2: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
Indexing and selecting data — pandas 1.3.4 documentation
Another common operation is the use of boolean vectors to filter the data. The operators are: | for or, & for and, and ~ for not. These must be grouped by using parentheses, since by default Python will evaluate an expression such as df['A'] > 2 & df['B']
pandas.pydata.org

이외에도 수집한 데이터를 활용하여 조회 수, 댓글 수의 변화 등을 보여주는 그래프를 그려 유튜브 채널을 분석할 수 있답니다!
(5) 댓글 가져오기
이번에는 동영상별 댓글을 수집해보겠습니다.
슈카월드 채널의 동영상 전체에 대한 댓글을 수집하는 것은 시간이 오래걸리므로 "소비더머니" 채널의 동영상 댓글을 수집해보겠습니다.

우선 이전 단계에서 채널id, 재생목록id, 동영상id 를 수집하기 위해 사용한 코드를 이용해 "소비더머니" 채널의 동영상 id 목록을 가져오겠습니다.
import pandas as pd
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
from oauth2client.tools import argparser
DEVELOPER_KEY = '' # 유튜브 API 키값을 입력하세요.
YOUTUBE_API_SERVICE_NAME = 'youtube'
YOUTUBE_API_VERSION = 'v3'
# 01_채널 id 가져오기
youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=DEVELOPER_KEY)
search_response = youtube.search().list(
    q = '소비더머니',
    order = 'relevance',
    part = 'snippet',
    maxResults = 50
).execute()
channel_id = search_response['items'][0]['id']['channelId']# 02_채널 내 재생목록 id 가져오기
youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=DEVELOPER_KEY)
playlists = youtube.playlists().list(
    channelId = channel_id,
    part = 'snippet',
    maxResults = 20
).execute()
df = pd.DataFrame()
for item in playlists['items']:
    item_dict = {}
    item_dict['playlist'] = item['snippet']['title']
    item_dict['playlist_id'] = item['id']
    df = df.append(item_dict, ignore_index = True)# 03_소비더머니 재생목록에 있는 동영상 id 가져오기
sobi_the_money = df[df['playlist'] == '소비더머니'].reset_index()['playlist_id'][0]
video_ids = []
video_titles = []
playlistitems_list_request = youtube.playlistItems().list(
    playlistId = sobi_the_money, 
    part = 'snippet',
    maxResults = 50
)
while playlistitems_list_request:
    playlistitems_list_response = playlistitems_list_request.execute()
    for item in playlistitems_list_response['items']:
        title = item['snippet']['title']
        video_id = item['snippet']['resourceId']['videoId']
        
        video_titles.append(title)
        video_ids.append(video_id)
    
    playlistitems_list_request = youtube.playlistItems().list_next(
        playlistitems_list_request, playlistitems_list_response
    )
video_df = pd.DataFrame()
video_df['video_title'] = video_titles
video_df['video_id'] = video_ids
위의 영상중 삼성전자 휴대폰을 주제로 한 '10년을 아이폰과 중국산에 치이고, 30년을 불태우고 접고 몸부림치며 만든 세계 1등, 삼성 휴대전화 이야기 / 소비더머니' 라는 제목의 영상 댓글을 수집해보겠습니다.
댓글을 수집하기 위해서는 commentThreads.list method를 사용합니다.
method에 대한 자세한 설명은 아래 공식 레퍼런스에서 확인할 수 있습니다.
https://developers.google.com/youtube/v3/docs/commentThreads/list
CommentThreads: list | YouTube Data API | Google Developers
CommentThreads: list Returns a list of comment threads that match the API request parameters. Quota impact: A call to this method has a quota cost of 1 unit. Common use cases Request HTTP request GET https://www.googleapis.com/youtube/v3/commentThreads Par
developers.google.com
comments = []
comment_list_response = youtube.commentThreads().list(
    videoId = 'spP4VXtumls', # 영상 id를 입력합니다.
    order = 'relevance',
    part = 'snippet,replies',
    maxResults = 100 # 댓글은 한번에 최대 100개씩만 요청할 수 있습니다
).execute()
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: # 댓글에 대한 댓글(reply)이 있는 경우 수집합니다
        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: # 아직 동영상에서 가져올 댓글이 남은 경우 nextPageToken을 기반으로 API를 다시 호출합니다
        comment_list_response = youtube.commentThreads().list(
            videoId = 'spP4VXtumls',
            order = 'relevance',
            part = 'snippet,replies',
            pageToken = comment_list_response['nextPageToken'],
            maxResults = 100
        ).execute()
    else:
        break
comment_df = pd.DataFrame(comments)
comment_df.columns = ['comment','author','date','like']

이상, 유튜브 API 키 활용하는 법!! 잘 따라오셨나요?!
이제 유튜브에서 제공하는 API를 활용하여 유튜브 컨텐츠와 관련된 데이터를 수집할 수 있습니다.
더 많은 API 활용법을 위해서는 YouTube API 공식 레퍼런스 문서를 참고하면 됩니다. :-)
https://developers.google.com/youtube/v3/docs
API Reference | YouTube Data API | Google Developers
API Reference YouTube Data API를 사용하면 YouTube 웹사이트에서 일반적으로 실행하는 기능을 사용자의 웹사이트 또는 애플리케이션에 통합할 수 있습니다. 아래 목록에서는 API를 사용하여 검색할 수 있
developers.google.com

'BLOG > 오픈소스 리뷰기' 카테고리의 다른 글
| [오픈소스 리뷰기] 번역 API 이용하기(2) - 네이버파파고, 카카오 번역 (0) | 2021.11.09 | 
|---|---|
| [오픈소스 리뷰기] 번역 API 이용하기(1) - Google 번역 (3) | 2021.11.08 | 
| [오픈소스 리뷰기] YouTube API 이용하기(1) - API 키 발급하기 (0) | 2021.11.03 | 
| [오픈소스 리뷰기] 공공데이터포털(2) - 전기차 충전소 정보 데이터 API 이용하기 (0) | 2021.11.01 | 
| [오픈소스 리뷰기] 공공데이터포털(1) - 지역별 코로나19 감염현황 데이터 API 이용하기 (0) | 2021.10.28 | 
 
									
								 
									
								 
									
								