본문 바로가기

BLOG/오픈소스 리뷰기

[오픈소스 리뷰기] YouTube API 이용하기(2) - API 키 활용하기

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

 

안녕하세요. 디노랩스입니다! 

지난번 포스팅에서 유튜브 API 키를 발급받는 법을 알려드렸는데요.

오늘은 발급받은 API 키를 어떻게 활용하는지 

  1. 검색결과 가져오기
  2. 재생목록 가져오기
  3. 재생목록 내 동영상 가져오기
  4. 동영상 정보 가져오기
  5. 댓글 가져오기

총 다섯가지 활용법을 리뷰해 드리겠습니다 :D

 

 

▽▼ 다시한번 보러가기 ▽▼

2021.11.03 - [BLOG/오픈소스 리뷰기] - [오픈소스 리뷰기] YouTube API 이용하기(1) - API 키 발급하기

 

 

02. API 키 활용하기

 

API를 활용하기 전에 먼저 아래의 pip 명령어를 이용해 Google api client 라이브러리를 설치하고 필요한 라이브러리를 import 합니다.

pip install google-api-python-client
from 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