見出し画像

【Python】プレイリスト内から動画情報を抽出する方法【備忘録改訂版】

 ご無沙汰してました。
 皆さまお元気でしたでしょうか?
 私は色々あり仕事を離れたり、新しいことを始めようと動き出したり、
ここ1年がかなり大きな転換期となってきております。
 今回なのですが、『Vtuber・Vsinger音楽動画観測記録』を毎週アップされているmikan_itoさんよりご依頼もあり、以前作成した、『【Python】プレイリスト内から動画情報を抽出する方法【備忘録】』にてプログラムを書いておりましたが、今回もmikan_itoより、short動画が多くあり、再生時間にて動画をshortなのか通常の動画なのか判断したいとの話があり、以前のプログラムを修正いたしましたので、備忘録として筆を執りました。


1.概要

 以前は、プレイリスト内に登録されている動画から以下の9要素を抽出するプログラムとなっていましたが、追加されたのは10番目となります。

①チャンネル名
②公開日
③動画タイトル
④動画URL
⑤再生数
⑥コメント数
⑦高評価(評価数が隠されているものは「-1」で表示されます)
⑧低評価(現在では低評価を表示できないため「-1」が返されます)
⑨概要欄

⑩再生時間【追加要素】

この10要素をエクセルシートにcsv形式で書き出します。

2.コード

from googleapiclient.discovery import build
import json
import openpyxl
import re
import isodate
import datetime
from datetime import date
from openpyxl.styles import Font


# 初期化

def initYoutube(API_KEY):
   API_SERVICE_NAME = "youtube"
   API_VERSION = "v3"
   return build(API_SERVICE_NAME, API_VERSION, developerKey=API_KEY)


# プレイリストIDを渡して動画IDリストを得る

def getIdListFromPlaylist(id_,youtube):

   nextPageToken = 'start'
   response = []

   while(nextPageToken is not None):

       if(nextPageToken == 'start'):
           search_response = youtube.playlistItems().list(
           part= 'snippet',
           playlistId=id_,
           maxResults = 50,
           ).execute()
       else:
           search_response = youtube.playlistItems().list(
           part= 'snippet',
           playlistId=id_,
           maxResults = 50,
           pageToken = nextPageToken
           ).execute()

       if('nextPageToken' in search_response):
           nextPageToken = search_response['nextPageToken']
       else:
           nextPageToken = None
       
       for item in search_response['items']:
           response.append(item['snippet']['resourceId']['videoId'])


   response.reverse()   
   return response


# YoutubeのAPIを使用し統計情報を取得する

def getCountDetails(id_, youtube):

   #50件に分割
   idLists = split_list(id_,50)
   response = []

   for idList in idLists:
       search_response = youtube.videos().list(
       part= 'statistics,snippet,contentDetails',
       id=idList,
       ).execute()

       response.extend(search_response['items'])
       
   return response


# 指定するワークシートからIDリストを取得して数値を更新する

def setCountDetail(ws,idList,youtube):
   result = getCountDetails(idList,youtube)
   row = 1
   
   ws.cell(row,1).value = 'チャンネル名'
   ws.cell(row,2).value = '公開日時UST'
   ws.cell(row,3).value = 'タイトル'
   ws.cell(row,4).value = 'URL'     
   ws.cell(row,5).value = '再生数'
   ws.cell(row,6).value = 'コメント数'
   ws.cell(row,7).value = '高評価'
   ws.cell(row,8).value = '低評価'
   ws.cell(row,9).value = '概要欄'
   ws.cell(row,10).value = '再生時間'

   row += 1

   for item in result:

       published = datetime.datetime.fromisoformat(item['snippet']['publishedAt'].replace('Z', '+00:00')).strftime('%Y/%m/%d %H:%M:%S')
       ws.cell(row,1).value = item['snippet']['channelTitle']
       ws.cell(row,2).value = published
       ws.cell(row,3).value = item['snippet']['title']
       ws.cell(row,4).value = 'https://www.youtube.com/watch?v='+item['id']
       ws.cell(row,9).value = item['snippet']['description']
       ws.cell(row,10).value = duration = isodate.parse_duration(item['contentDetails']['duration'])

       #非公開等がある場合は-1を表示
       ws.cell(row,5).value = int(item['statistics']['viewCount']) if 'viewCount' in item['statistics'] else -1
       ws.cell(row,6).value = int(item['statistics']['commentCount'])  if 'commentCount' in item['statistics'] else -1
       ws.cell(row,7).value = int(item['statistics']['likeCount'])  if 'likeCount' in item['statistics'] else -1
       ws.cell(row,8).value = int(item['statistics']['dislikeCount']) if 'dislikeCount' in item['statistics'] else -1

       #ws.cell(row,4).hyperlink = ws.cell(row,3).value
       ws.cell(row,5).number_format = '#,##0'
       ws.cell(row,6).number_format = '#,##0'
       ws.cell(row,7).number_format = '#,##0'
       ws.cell(row,8).number_format = '#,##0'


       row += 1

# 配列を指定した個数ごとに分割

def split_list(l, n):
   for idx in range(0, len(l), n):
       yield l[idx:idx + n]

# YoutubeAPI用キーの提示

API_KEY = '各自所得したキーを入力' 
FILENAME = 'Youtube'
youtube = initYoutube(API_KEY)

#「ワークシート名:プレイリストID」の辞書配列作成
playList = {
'Vtuber music':'PLzzbUvy2gzmceU9mPP81yvsKjuSqgxbSx',


}

# Excelファイル新規作成
wb = openpyxl.Workbook()

for key in playList:
   wb.create_sheet(key,0)
   setCountDetail(wb[key],getIdListFromPlaylist(playList[key],youtube),youtube)    

#タイムスタンプ付けて保存
dt_now = datetime.datetime.now()
wb.save(FILENAME+dt_now.strftime('_%Y%m%d_%H%M')+'.xlsx')

コードは上記の通りになります。
大きな変更点としては、以下の追加となります。

       ws.cell(row,10).value = duration = isodate.parse_duration(item['contentDetails']['duration'])

 『contentDetails』内には動画の長さとアスペクト比を含む、動画コンテンツに関する情報が格納されております。
 その中の『contentDetails.duration』を使用し、ISO 8601 に従って、持続期間を PT#M#S の形式で表示したものが記載されますが、「isodate.parse_duration」を使用することにより、ISO 8601 形式を正規表現にてcsv形式で出力することが可能となっております。
 必要なパッケージにつきましては、適宜pipインストールを実施するようお願い致します。

3.まとめ

 久しぶりの記事が以前の備忘録の改訂になるとは思っておりませんでしたが、久しぶりの生存報告という形で記事を上げることができたので内心良かったと思っております。
 これから少しずつでも新しい記事を書いていけるよう準備を進めたいと思いますので、皆さま引き続きよろしくお願いいたします。

4.おわりに

 最後にちょっとした宣伝を。
 本日このnoteの話題になったソースコードをご依頼いただいたmikan itoさんと共同にて運営させていただいているDiscordサーバをVtuber・Vsinger・Vliverのファンに向けて開放しています。

 主に、創作やV全般の情報交換・布教などの場にできればと思っています。ご興味ありましたら是非覗いてみてください。
 ライトユーザー多めですのであまりビビらずに入ってきてもらえればと思います。活動者の方も入っていただいても問題ありません。活動者専用のカテゴリ等も準備中です。詳細は下記のツイートとサーバの必読をご覧ください。


この記事が気に入ったらサポートをしてみませんか?