YouTubeリサーチするGASプログラムはスプレッドシートに直接エンゲージメント率を出力できるの担当者必見
こんにちは!【YouTubeで結果を出す】には、その時々の傾向を把握することが大事ですよね。
傾向といっても、なんとなく追っているだけでは置いていかれるばかりです。
エンゲージメント率を算出し、可視化することはYouTubeリサーチの上で今や最低限です。
エンゲージメント率の算出自体は簡単です。
エンゲージメント率の計算方法
エンゲージメント率=エンゲージメント数(高評価数+コメント数)÷再生回数×100
問題は「数」です。
リサーチする上ではサンプル数が多いほど有効性が上がります。どんな計算をしても、サンプル数が少なければ意味がありません。
一度に大量のデータをサンプリングして初めてリサーチと言えるのです。
一度にYouTube動画情報のデータを取得するにはどうすれば良いでしょうか?
YouTube API を使って動画情報を取得しよう
YouTube API自体の使い方は簡単で、必要な値をを設定したURLを叩くだけでjson形式の情報をスラスラと取得できます。
https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=UUyhBnB7_27lhyaYgjCf9Z4g&maxResults=50&order=date&pageToken=&key=ここにKey
後ほど、API Keyの取得フローも紹介します。
ここまでは簡単なのです。問題は、json形式の情報をいかに大量に、簡単に、リサーチ分析可能なスプレッドシートの状態にするかなのです。
一発でGoogleスプレッドシートに出力しどこからでもリサーチ可能
方法はいくつもあると思います。PythonでCSVとして出力するのもアリだと思います。しかし、CSVデータからリサーチするのも意外と面倒なんですよね。
まずそのCSVファイルをどこに保存するか…クラウドでお手軽に開きたいけど、そこも自動化するとなると、ログインしたりなにかと手順が多い。
そこで、身近でお手軽で動作も軽いGoogleスプレッドシート!スプレッドシート系はこれだけで良いと言っても過言ではありません。
そこで…
Googleスプレッドシートを開いて…
チェックしたいチャンネルのIDを入力して…
var channelID = "xxx";
実行ボタンを押せば…
▶︎RUN!
はい。Googleスプレッドシートに直接データが出力されます!!
パチパチ。
これはGAS(GoogleAppsScript)を使います。
後述するプログラムを貼り付けるだけなので、GAS初心者だけでなく、プログラム初心者にもオススメです。
ではフローを書いていきますね。
YouTube API Keyを取得
※別記事にまとめますのでお待ち下さい。
Googleスプレッドシートでスクリプトエディタを開く
適切なGoogleアカウントでスプレッドシートを開きます。
スクリプトエディタにプログラムを貼り付ける(初回のみ)
スクリプトエディタ内で「ファイル」「スクリプトの追加」をします。バージョンによって+ボタンだったりします。
上部太文字のスクリプトの名前も適宜変えます。
それから、下記プログラムを貼り付けます。
function get_video_list() {
var today = new Date();
Logger.log(today);
var myToday = Utilities.formatDate(today,'Asia/Tokyo', "YYYY-MM-dd-HHmm");
Logger.log(myToday);
// パラメータを設定 ==================================================
// 作成したAPI key
var apikey = '取得したkey';
// 書き込み先のシート名
var sheetName = "samp"+myToday;
//var sheetName = "samp; //同じシートタブに未取得データ追記する場合にはシート名を指定する
// チェックしたいチャンネルのID
var channelID = "UCCy_q-N7F2FOIZ6ZggHIAKg"; //sony sample
// チェックする範囲の設定
// true : 最新50件のみチェックする。 (2回目以降の実行(定期実行時)はtrueを推奨)
// false: 対象チャンネルの全動画を取得する。
var getNewVideoOnly = true;
insertSheet(sheetName);
// スプレッドシートに記録済みの情報を取得 ==================================================
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getSheetByName(sheetName);
var recorded_video_IDs_array = [];
if (sheet.getLastRow() > 2) {
recorded_video_IDs_array = sheet.getRange(2,4,sheet.getLastRow()-1,1).getValues() || []; //getRange(行番号, 列番号, 行数, 列数)
}
else {
recorded_video_IDs_array = [];
}
var recorded_video_IDs_hash = {};
for (var i=0; i<recorded_video_IDs_array.length; i++) {
recorded_video_IDs_hash[recorded_video_IDs_array[i]] = 1;
}
// YouTube Data APIを叩いてチャンネル情報を取得 ==================================================
// 「アップロードされた動画リスト」のIDを取得
var baseUrl = "https://www.googleapis.com/youtube/v3/";
var dataURL = baseUrl + 'channels?part=contentDetails&order=date&id=' + channelID + '&key=' + apikey;
var response = UrlFetchApp.fetch(dataURL);
var responseJson = JSON.parse(response.getContentText());
var uploads_video_play_list_ID = responseJson.items[0].contentDetails.relatedPlaylists.uploads;
var page_token = '';
var record_data = [];
// 各動画の情報を取得
while (page_token !== undefined) {
dataURL = baseUrl + 'playlistItems?part=snippet&playlistId=' + uploads_video_play_list_ID +
'&maxResults=50&order=date&pageToken=' + page_token + '&key=' + apikey;
//'&maxResults=50&order=date&key=' + apikey;
response = UrlFetchApp.fetch(dataURL);
responseJson = JSON.parse(response.getContentText());
page_token = responseJson.nextPageToken;
//データをプッシュします
record_data.push(['タイトル', 'URL', '長さ','再生回数','高評価数','低評価数','コメント数','投稿日','サムネイル','エンゲージメント','エンゲージメント率','集計日']);
// スプレッドシートに未記録の情報だけを抜き出す ==================================================
for (var i=0; i<responseJson.items.length; i++) {
// 動画情報取得
var video_id = responseJson.items[i].snippet.resourceId.videoId;
var video_title = responseJson.items[i].snippet.title;
var thumbnail_url = responseJson.items[i].snippet.thumbnails.default.url;
var publishedAt = responseJson.items[i].snippet.publishedAt;
var publishAtJST = Utilities.formatDate(new Date(publishedAt), "JST", "yyyy/MM/dd HH:mm:ss");
//投稿日差分
var todayMoment = Moment.moment(); //現在日時
var pubMoment = Moment.moment(publishAtJST,'JST',"yyyy/MM/dd HH:mm:ss"); //投稿日
var difference = todayMoment.diff(publishedAt,"d"); //
// 記録済みならスキップ
if (recorded_video_IDs_hash[video_id]) {
continue;
}
// 他のスキップする条件があれば記述
//(サンゼさんのチャンネルの場合、タイトルが「数字.」から始まるものがチュートリアルなのでそれ以外はスキップ。)
/*
if (! video_title.match(/[0-9]+\./)) {
continue;
}
*/
// スプレッドシートに書き込む文字列を整える
var video_url = 'https://youtube.com/watch?v=' + video_id;
var cell_value_title = '=hyperlink("' + video_url + '","' + video_title + '")';
var cell_value_thumbnail = '=image("' + thumbnail_url + '")';
// 動画の時間を取得
var video_duration = '';
dataURL = baseUrl + 'videos?part=contentDetails&id=' + video_id + '&key=' + apikey;
response = UrlFetchApp.fetch(dataURL);
var responseJson_video = JSON.parse(response.getContentText());
video_duration = convertDurationTime(responseJson_video.items[0].contentDetails.duration);
//original 再生回数
var count_view = '';
var count_like = '';
var count_dislike = '';
var count_comment = '';
var engagement='';
var engagement_per='';
dataURL = baseUrl + 'videos?part=statistics&fields=items%2Fstatistics&id=' + video_id + '&key=' + apikey;
response = UrlFetchApp.fetch(dataURL);
var responseJson_count = JSON.parse(response.getContentText());
count_view = responseJson_count.items[0].statistics.viewCount;
count_like = responseJson_count.items[0].statistics.likeCount;
count_dislike = responseJson_count.items[0].statistics.dislikeCount;
count_comment = responseJson_count.items[0].statistics.commentCount;
engagement=Number(count_like)+Number(count_comment);
engagement_per=engagement/count_view;
//データをプッシュします
record_data.push([video_title, video_url, video_duration,count_view,count_like,count_dislike,count_comment,publishAtJST,cell_value_thumbnail,engagement,engagement_per,today]);
}
// 新しい動画のみ取得する場合、次のページを検索しない
if (getNewVideoOnly) {
page_token = undefined;
}
}
// スプレッドシートに書き込む ==================================================
if (0 < record_data.length) {
var last_row = sheet.getRange("B:B").getValues().filter(String).length + 1;
sheet.getRange(last_row, 1, record_data.length, 12).setValues(record_data);
newConditionalFormatRule("M2:M999",1,10,'General');
newConditionalFormatRule("K2:K999",0.1,1,'0.00%');
setNumberFormat("K2:K999");
whenDateAfter("H2:H999");
}
}
function convertDurationTime(duration) {
var reg = new RegExp('^PT([0-9]*H)?([0-9]*M)?([0-9]*S)?');
var regResult = duration.match(reg);
var hour = regResult[1];
var minutes = regResult[2];
var sec = regResult[3];
if(hour == undefined) {hour = '00';}
else {
hour = hour.split('H')[0];
if(hour.length == 1){hour = '0' + hour;}
}
if(minutes == undefined) {minutes = '00';}
else {
minutes = minutes.split('M')[0];
if(minutes.length == 1){minutes = '0' + minutes;}
}
if(sec == undefined) {sec = '00';}
else {
sec = sec.split('S')[0];
if(sec.length == 1){sec = '0' + sec;}
}
return hour + ":" + minutes + ":" + sec
}
function insertSheet(sheetName) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.insertSheet(sheetName, 1);
}
function newConditionalFormatRule(odrcol,min,max,format) {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange(odrcol);
var rule = SpreadsheetApp.newConditionalFormatRule()
//.whenFormulaSatisfied('=$B:$B=max(B:B)') // B列で一番大きい値
.whenNumberBetween(min,max)
.setFontColor("#FF0000")
.setBackground("#FFC0CB")
.setBold(true)
.setRanges([range])
.build();
var rules = sheet.getConditionalFormatRules();
rules.push(rule);
sheet.setConditionalFormatRules(rules);
}
function whenDateAfter(odrcol) {
// セルに条件付き書式規則を追加して、
var MyDate = new Date();
MyDate.setDate(MyDate.getDate() - 10);
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange(odrcol);
var rule = SpreadsheetApp.newConditionalFormatRule()
.whenDateAfter(new Date(MyDate))
.setFontColor("#FF0000")
.setBackground("#FFC0CB")
.setBold(true)
.setRanges([range])
.build();
var rules = sheet.getConditionalFormatRules();
rules.push(rule);
sheet.setConditionalFormatRules(rules);
}
function setNumberFormat(odrcol) {
var sheet = SpreadsheetApp.getActiveSheet();
var rangeList = sheet.getRangeList([odrcol]);
// 指定された範囲に対して常に3つの小数点を表示します。
rangeList.setNumberFormat('0.00%');
}
忘れずに保存ボタンを押します。
パラメータの変更
以下のようにパラメータを設定します。
忘れずに保存ボタンを押します。
実行
「関数を選択」から「get_video_list」を選びます。
初回のみ「許可を確認」を押します。
初回のみ 作業するアカウントをえらびます。
初回のみ 小さな「詳細」を押します。
「安全ではないページに移動」と出ますのでそちらを押します。
データの確認
処理が終わったら、新しいシートタブが出来ていることを確認します。
以上です。一目瞭然でデータが捗ります。嬉しいですね!
問題■1200件以上のデータ取得について
この方法で、1200件が3、4分で取得可能です。
しかし、データ取得に6分以上の時間がかかりますと、エラーが出て取得が2020年12月現在できません。
こちらは次回解決していきたいと思います!
次回
・1200件以上のデータを取得する
・開始投稿日を設定する
それでは!データを取得して一歩先へ行きたい方是非フォローお願いします。
この記事が気に入ったらサポートをしてみませんか?