0.今回の依頼内容
前回の続きです! YouTubeAPIを叩く
【今回の仕様】
キーワード検索で、数か月で登録者1000人突破したチャンネルを抽出
実際に動かしたのものが、こちら。
#YouTube で1000人登録って大変
— 【現役PG】Don't Pray Debug(プレイさん) (@DebugDon) November 26, 2022
サンプルは
・検索ワード「#チェンソーマン」
・チャンネル開設から6か月以内で1000人突破
・昨日までに何らかの投稿をした
・日本のチャンネル
75チャンネルあって9チャンネルが条件に合う…と
こう見ると、やっぱ狭き門なのね
API使ったんで、また解説記事かきます pic.twitter.com/rZDsiEneO3
この依頼内容からAPIの仕様も加味して以下の処理内容で実装しました。
-
Searchを使ってチャンネル検索
- 期限(指定しないと、チャンネルの詳細検索ができないため)
- チャンネル開設日の抽出(プログラミングで対応)
-
Channelsを使ってチャンネルの詳細を調べる(チャンネルIDで検索)
- 登録者数が1000突破してる(プログラミングで対応)
- チャンネル開設場所が日本(プログラミングで対応)
では、順番に解説していきます!
1.日付作成
YouTubeAPIの日付はフォーマットが決まっているので
フォーマットに合わせた日付を作ります。
//※GASのコードです
const day = new Date();
//今日の日付
TODAY = Utilities.formatDate(day,"JST","yyyy-MM-dd'T'HH:mm:ss'Z'");
let setChannelDay = day;
//MONTHか月前
setChannelDay.setMonth(setChannelDay.getMonth() - MONTH);
CHANNELDAY = Utilities.formatDate(setChannelDay,"JST","yyyy-MM-dd'T'HH:mm:ss'Z'");
let setBeforeDay = day;
//DAY日前
setBeforeDay.setDate(setBeforeDay.getDay() - DAY);
BEFOREDAY = Utilities.formatDate(setBeforeDay,"JST","yyyy-MM-dd'T'HH:mm:ss'Z'");
2.Searchを叩く(51件以上 検索したい)
今回のメイン解説
YouTubeAPIの仕様では1リクエスト50件がMAXです。
なので51件以降のデータをゲットするのは、ちょっとコツがいります。
function APISearch(){
//API側の仕様
let URL = "https://www.googleapis.com/youtube/v3/search";
URL += "?part=snippet";
//50件(MAX値)
URL += "&maxResults=" + LIMIT;
URL += "&order=date";
//対象期間
URL += "&publishedBefor=" + BEFOREDAY;
URL += "&publishedAfter=" + TODAY;
//キーワード指定
URL += "&q=" + WORD;
/*
//両方のワードを含む
const WORD = "犬 ネコ";
//どちらかのワードを含む
const WORD = "魔王 OR 天使";
*/
//チャンネルを対象
URL += "&type=channel";
//2回目以降の処理(51以降を検索する)
if(pageToken != ""){
URL += "&pageToken=" + pageToken;
}
URL += "&key=" + APIKEY;
const response = UrlFetchApp.fetch(URL);
const json = JSON.parse(response);
/*抽出の判定式*/
//51件以上ある場合
if(json.nextPageToken){
//次のトークン入れ込み
pageToken = json.nextPageToken;
//もう一回Searchを叩く
APISearch();
}
}
これで51件以上あっても条件に合うすべてのデータを取得することができます。
3.抽出条件とChannels前処理
Channelsも同様に1リクエスト50件がマックスなので
そちらの対応をしたコードが、こちらです
function APISearch(){
/*API叩くとこまで*/
//該当データがない
if(!json.items || json.items.length == 0){
//APIChannels呼び出し処理
CallChannels();
return;
}
for(let i=0; i<json.items.length; i++){
//フォーマットを指定して日付を作成
const At = Utilities.formatDate(new Date(json.items[i].snippet.publishedAt),"JST","yyyy-MM-dd'T'HH:mm:ss'Z'");
if(At > CHANNELDAY){
//データ入れ込み
idList.push(json.items[i].snippet.channelId);
}
}
if(json.nextPageToken){
/*もう一回Searchを叩く*/
}else{
//APIChannels呼び出し処理
CallChannels();
return;
}
}
//APIChannels呼び出し処理
function CallChannels(){
if(idList.length == 0){
console.log("処理終了");
return;
}else{
if(idList.length <= 50){
//そのままjoinしてAPIを叩く
APIChannels(idList.join(","));
}else{
//配列から50件を抜き出す
let setIdList = idList.splice(0,50);
//MAX50件でチャンネル検索
APIChannels(setIdList.join(","));
//もう一回呼び出す
CallChannels();
}
}
}
4.条件に合うチャンネルデータの取得
ココは前回、やったとこなのでサラッといきます
function APIChannels(id){
let URL = "https://www.googleapis.com/youtube/v3/channels";
URL += "?part=snippet,statistics";
URL += "&maxResults=" + LIMIT;
URL += "&id="+id;
URL += "&key="+ APIKEY;
const response = UrlFetchApp.fetch(URL);
const json = JSON.parse(response);
//書き出し対象データ
let writeData = [];
let channelIdList = id.split(",");
for(let i=0; i<json.items.length; i++){
if(json.items[i].statistics.subscriberCount >= SUBSCRIVER && json.items[i].snippet.country == "JP"){
//必要なデータ類(チャンネル名チャンネル作製日,登録者数)
let channelData = [];
channelData.push(json.items[i].snippet.title);
channelData.push(channelIdList[i]);
let at = json.items[i].snippet.publishedAt;
at = at.substring(0,at.indexOf("T"));
channelData.push(at);
channelData.push(json.items[i].statistics.subscriberCount);
//書き出し用配列に叩き込む
writeData.push(channelData);
}
}
if(writeData.length > 0){
console.log("シートに書き込みます");
/*スプレッドシートに書き出し*/
}
}
以上!
質問、依頼等がありましたらTwitterにてお話、聞きます。
Twitter: Don't Pray Debug