11
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

YouTuberマイニング #1

Last updated at Posted at 2018-06-27

YouTubeとYouTuberが好きです。
本記事は、自分を含むYouTuberファンがなぜ好きになるのかを解析するためのデータ分析を行う記事です。
これはシリーズ的に更新していきます。

この記事でやったこと

  • YouTube Data APIでChannelから情報を取得する方法を試す
  • 取得した情報をDataFrame(pandas)に格納する
image.png

上の画像は可愛い女性YouTuber "ゆきりぬ"さんのチャンネル↓から取得したデータ。
image.png

コードと解説

コードここにある
haradai1262/Notebooks-for-youtube-api-usage

1. YouTube Data APIとの接続

import sys

from apiclient.discovery import build
from apiclient.errors import HttpError
from oauth2client.tools import argparser

import devkey
DEVELOPER_KEY = devkey.api
YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"
CHANNEL_ID = 'UCMsuwHzQPFMDtHaoR7_HDxg' # channel id of japanese popular (and cute) youtuber "Yukirinu"

# connection build
YT = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=DEVELOPER_KEY)

こちらはYouTubeのAPIと接続するためのコードです。
'DEVELOPER_KEY'は自分で取得する必要があるので注意。
YouTube Data API v3の概要
DEVELOPER_KEYの取得方法

CHANNEL_IDは、チャンネルのURLが"https://www.youtube.com/channel/UCMsuwHzQPFMDtHaoR7_HDxg" の場合は、"UCMsuwHzQPFMDtHaoR7_HDxg"です。

2. チャンネルの動画リストを取得

def get_channel_vlist( yt, cid, max_num ):
    channel_videos_tmp = []
    feed = yt.search().list( channelId=cid, maxResults=1, order='date', type='video', part='id' ).execute()
    nextPageToken = feed[ 'nextPageToken' ]
    video_idx = 1
    while 1:
        if video_idx > max_num: break
        video_idx += 1
        if not 'nextPageToken' in feed: break 
        nextPageToken = feed[ 'nextPageToken' ]
        vid = feed.get('items')[0]['id']['videoId']
        channel_videos_tmp.append( vid )
        feed = yt.search().list( channelId=cid, maxResults=1, order='date', type='video', part='id', pageToken = nextPageToken ).execute()
    return channel_videos_tmp

channel_videos = get_channel_vlist( YT, CHANNEL_ID, 10 )

こちらでは、CHANNNEL_IDから投稿動画をIDを取得します。
なお、APIの仕様上?、このコードだと最大500件程度しか取得できません。
※ うまいことスクレイピングすれば、すべて取得できるかと思います。timestamp確認して複数回実行するとか...

3. 動画リストから各動画の情報を取得

def get_video_detail( vid ):
    video_detail = YT.videos().list(part="id,snippet,statistics,contentDetails,topicDetails",id=vid).execute()
    return video_detail.get("items",[])[0]

vlist_details = [ get_video_detail( i ) for i in channel_videos ]    
channel_video_info = {} # { idx : video_details(dictionary) }
for i, v_detail in enumerate(vlist_details):
    channel_video_info[i] = v_detail

こちらでは先ほど取得した動画IDのリストから各動画の詳細を取得しています(JSON形式)。
YouTube Data APIでは、タイトル・タグ・説明文や視聴数・いいね数などの統計値など様々な情報が取得できます。
こちらのコードでは、"part="id,snippet,statistics,contentDetails,topicDetails"で取得する情報を選択しています。
取得可能な情報の詳細は以下に記載されています。
Videos: list  |  YouTube Data API (v3)

4. 取得した動画情報をデータフレーム化

info_tree = {
    'id': None,
    'snippet': ['title','description','liveBroadcastContent','tags','publishedAt','thumbnails'],
    'statistics': ['viewCount','likeCount','favoriteCount','dislikeCount','commentCount'],
    'contentDetails':['caption','definition','dimension','duration','projection'],
    'topicDetails':['TopicIds', 'relevantTopicIds'],
}

df_cols = []
for parent, child in info_tree.items():
    if child == None: df_cols.append( parent )
    else:
        for c in child: df_cols.append( c )

rows = []
for i, v in channel_video_info.items():
    row = []
    for parent, child in info_tree.items():
        if child == None: row.append( v[parent] )
        elif parent == 'snippet':
            for c in child:
                if c == 'thumbnails':
                    row.append( v[parent][c]['default']['url'] )
                elif c == 'tags':
                    if not 'tags' in v['snippet']: row.append( None )
                    else: row.append( v[parent][c] )
                else:
                    row.append( v[parent][c] )
        elif parent == 'topicDetails':
            if 'topicDetails' in v:
                for c in child:
                    if c in v[parent]: row.append( v[parent][c] )
                    else: row.append( None )
            else:
                row.append( None )
                row.append( None )
        else:
            for c in child: row.append( v[parent][c] )
    rows.append( row )

こちらでは、取得した動画の情報をDataFramenに格納するために整理しています。
JSONで取得されている各データを1行のレコードにするために色々しているんですが、結果ごちゃごちゃですね。まぁ動けばいいさ。
※ 最初は綺麗だったんですが、例外処理(topicIdがないデータがある、tagsがないデータがある、など)を追加しているとめっちゃ汚くなりました。いつか整理します...

import pandas as pd
df = pd.DataFrame( rows, columns=df_cols )
print( df.shape )
df.head()
image.png

最後にデータフレームに格納して終わりです。
いい感じになりました。

取得したデータを使っての分析は#2で

つぶやき

  • YouTuberのデータセット公開してみたいかも、有名YouTuberのリスト欲しいからスクレイピングに適当なサイトあれば知りたい
  • 簡単なところで、チャンネル登録者数に対する動画の視聴数やいいね(Like)数でファンの熱量みたいなものを分析できる
  • こんなことやってみたら?みたいな要望お待ちしております!
11
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?