はじめに
これは、Spreadsheets/Excel Advent Calendar 2020の25日目の記事となります。
6日遅れの大晦日に書いていますけどね。
- 【Python】Youtube Data Apiを使ってYouTube 動画コメントを全取得する
- 【VBA】ExcelでYoutube Data Apiを使ってYouTube 動画コメントを全取得する
- 【VBA】Excel for MacでYoutube Data Apiを使ってYouTube 動画コメントを全取得する
- 【.NET】Youtube Data Apiを使ってYouTube 動画コメントを全取得する
どんだけ同じネタを使い回すのか、とはいえ、GoogleAppsScrip(GAS)版を作ってなかったんだよね。
環境
- Windows 10 Home
- Google.Apis.Youtube.v3 v1.49.0.2173
準備
Apps Script画面のサービスにて、YouTube Data APIを追加してください。
サービスの横の「+」をクリックし、YouTube Data API を選択して追加します。
仕様
コメントのフォーマットはhtmlかplain textがあるのですが、plain textになっています。
並び順はrelevanceで評価順が多い順にしています。子コメントについては順不動(並び順を指定しても動画サイトと同じにならない)です。
※APIの使用回数を減らすため 親コメントはmaxResults=100、子コメントはmaxResults=50とする。
※コメントでは低評価(disLike)数は取得できない。
(連番) (親コメント) (グッド数) (投稿者名) (投稿日時) (返信数)
(連番) (子連番) (子コメント) (グッド数) (投稿者名) (投稿日時)
【2021/05/28追記】
並び順を評価順(relevance)にした場合、YouTube Data API v3の制約上2000件を超える親コメントが取得できません。
並び順を新しい順(time)にした場合、上限が不明ですが2000件を超える親コメントが取得できます。
使用方法
function getYouTubeComment() {
let video_list = ['(Video IDを入力)'];
for (let i = 0; i < video_list.length; i++) {
let video_id = video_list[i];
getComment(i, video_id);
}
}
シート名には動画のタイトルがセットされます。
今回はリストになっているため、複数指定することができシートごとに動画コメントが出力されます。
let video_list = ['(Video IDを入力)', '(Video IDを入力)'];
Video IDを入力
例えば、「https://www.youtube.com/watch?v=oeJ_b0iG9lM」であれば、oeJ_b0iG9lM
がVideo IDとなりますので、プログラムの(Video IDを入力)を対象動画のVideo IDに書き換えてください。
なVideo IDに書き換える場合には括弧は不要です。気を付けてください。
let video_list = ['oeJ_b0iG9lM'];
プログラム
function getYouTubeComment() {
let video_list = ['(Video IDを入力)'];
for (let i = 0; i < video_list.length; i++) {
let video_id = video_list[i];
getComment(i, video_id);
}
}
// コメント取得
function getComment(i, video_id) {
let ss = SpreadsheetApp.getActiveSpreadsheet();
let pageToken = '';
let video = YouTube.Videos.list('id,snippet, statistics', {id: video_id,});
let sh;
if (i == 0) {
sh = ss.getActiveSheet();
} else {
sh = ss.insertSheet();
}
sh.setName(video.items[0].snippet.title);
sh.clear();
let row = { value: 1 };
let values = new Array('連番', '子連番', 'コメント', 'グッド数', '投稿者名', '投稿日時', '返信数');
output(row, sh, values);
let no = 1;
while (true) {
let comment_list = YouTube.CommentThreads.list('id, replies, snippet', {
videoId: video_id,
maxResults: 100,
order: 'relevance',
textFormat: 'plaintext',
pageToken: pageToken,
});
for (let j = 0; j < comment_list.items.length; j++) {
// 総返信数
let replyCount = comment_list.items[j].snippet.totalReplyCount;
let item = comment_list.items[j].snippet.topLevelComment.snippet;
outputItem(no, '', row, sh, item, replyCount);
if(replyCount > 0) {
if(replyCount == comment_list.items[j].replies.comments.length) {
for (let k = 0; k < comment_list.items[j].replies.comments.length; k++) {
let item2 = comment_list.items[j].replies.comments[k].snippet;
outputItem(no, k + 1, row, sh, item2, '');
}
}
else{
// 親ID
let parentID = comment_list.items[j].snippet.topLevelComment.id;
getReplyComment(sh, no, row, parentID);
}
}
no++;
}
pageToken = comment_list.nextPageToken;
if (typeof pageToken == 'undefined') {
break;
}
}
}
// 返信コメント取得
function getReplyComment(sh, no, row, parentID) {
let cno = 1;
let pageToken = '';
while (true) {
let comment_list = YouTube.Comments.list('id, snippet', {
maxResults: 50,
parentId : parentID,
textFormat: 'plaintext',
pageToken: pageToken,
});
for (let j = 0; j < comment_list.items.length; j++) {
let item = comment_list.items[j].snippet;
outputItem(no, cno, row, sh, item, '');
cno++;
}
pageToken = comment_list.nextPageToken;
if (typeof pageToken == 'undefined') {
break;
}
}
}
// データ出力
function outputItem(no, cno, row, sh, item, replyCount) {
// コメント
let text = item.textDisplay;
// グッド数
let likeCount = item.likeCount;
// ユーザー名
let authorName = item.authorDisplayName;
// 投稿日時
let publishedAt = localDate(item.publishedAt);
values = Array(no, cno, text, likeCount, authorName, publishedAt, replyCount);
output(row, sh, values);
}
// Google Spread Sheetに出力
function output(row, sh, values) {
for(let i = 0; i < values.length; i ++) {
sh.getRange(row.value, i + 1).setValue(values[i]);
}
row.value++;
}
// 日本日時に変換
function localDate(dt) {
return Utilities.formatDate(new Date(dt), 'JST', 'yyyy-MM-dd HH:mm:ss');
}
実行結果
郡司りかさんを御存知でしょうか?
マツコ・デラックスさんと村上信五(関ジャニ∞)さんがMCの「月曜から夜更かし」の中で、運動音痴として注目を浴びた女性です。
郡司りかさんはYoutubeとTwitterをやられており、ツイート画像に「おはよー」を隠すという遊びをしています。
郡司りかさんのツイート画像の「おはよー」を見つける
「【NiziU】郡司さんMake You Happyにチャレンジ (練習前)」の動画コメントを取得すると、下記のようになります。
他のプログラム言語と違い
API_KEYの指定が不要
他のプログラム言語ではAPI_KEYを指定していたのですが、Google Apps Scriptでは指定は不要でした。
返信コメントの取得
他のプログラム言語と違い返信コメントは5件までだったら、item.snippet.replies.comments
の配下で取得出来るので、それで負荷を減らしています。ほとんどの返信コメントは数件ですから、それで充分です。
最後に
初めて本格的に GoogleAppsScript と Googleスプレッドシート を使いましたけど、これは連携させるとすごく楽ですね。
仕事だとExcelメインで Googleスプレッドシートを使う機会がなかったので、さわって来なかったんだけど。
Google Colaboratory と Googleスプレッドシートで連携できそうだし積極的に使っていくことにします。