YouTubeのAPIを使用し、YouTubeスクレイピング的なことをやりたいと想います。

また、この記事は長くなりそうなので、何回かにわけて記載していってます。

今回はAPIを利用した最新動画を取得するように実装していきたいと思います。

また、実装方法については温かい目でみてください…。いろんなやり方があると思いますので参考程度になれば幸いです…。

前回

前回はAPI実行編として記載しました。

API実行方法としてはパラメータに欲しい情報やフィルタを設定し実行してみました。今回はその続きです。

シートを用意

APIを使用した結果を表示するシートとチャンネルID一覧を記載するシートの2つ用意します。

「LatestSongList」シート

「LatestSongList」シートを用意します。ここのシートにAPI結果を表示していきます。

「ChannelID」シート

「ChannelID」シートを用意します。

わかりやすいようにチャンネルIDとそのアーティスト名を表にしたいと思います。

ヘッダーをB1セルとC1セルに書き、内容はヘッダーの下に記載していきます。

簡易的ではありますが、以下のように表を作りました。

・実際のデータ

ChannelIDArtist Name
UCsN8M73DMWa8SPp5o_0IAQQTomorrowland
UC0VOyT2OCBKdQhF3BAbZ-1gAriana Grande`

・表にしたもの(簡易的…)

実装

データ収集する

APIでデータ収集しセルに情報を表示しているメソッドです。

function DataCollection() {
  
  //チャンネルIDを取得 ・・・①
  var URL = GetChannelId();
  
  var jsonData = [];
  
  for(var urlint = 0; urlint < URL.length; urlint++){
    //jsonデータの取得ができるか検証
    try{
      // JSONデータを取得 ・・・②
      var json = UrlFetchApp.fetch(URL[urlint]).getContentText();
      jsonData[urlint] = JSON.parse(json);
    }
    catch(e){
      Browser.msgBox(urlint + "個目のJsonデータが取得できませんでした\\n" + e);
    }
  }
  
  //セルを削除 ・・・③
  DeleteCell();
  
  var jsonint = jsonData.length;
  
  for(var i = 0; i < jsonint; i++){
    //jsonData配列に格納 ・・・④
    for(var jsonDataint=0; jsonDataint<3; jsonDataint++){
      try{
        //channelTitleを取得
        strChannelTitle.push(jsonData[i]["items"][jsonDataint]["snippet"]["channelTitle"]);
        
        //titleを取得
        strVideoTile.push(jsonData[i]["items"][jsonDataint]["snippet"]["title"]);
        
        //videoIdを取得
        var strVideId = jsonData[i]["items"][jsonDataint]["id"]["videoId"];
        //VideoIdとURLを結合
        strVideoURL.push(VideoURL + strVideId);
        
        //ReleaseDateを取得
        strReleaseDate.push(jsonData[i]["items"][jsonDataint]["snippet"]["publishedAt"]);
      }
      catch(e){
      }
    }
    
  }
  //配列の値をセルに表示 ・・・⑤
  ArrayDisplay(strChannelTitle,strVideoTile,strVideoURL,strReleaseDate,jsonint);
  
}

①・・・「ChannelID」シートからチャンネルIDを取得します。別のメソッドで実装してます。[チャンネルIDを取得し配列に格納する]で記載してます。

②・・・チャンネルIDが入った配列をループさせJSON構造にしてます。

③・・・データが表示されるセルを初期化してます。[セルを初期化する]で記載してます

④・・・JSONデータ内の各リソースの種類を取得します。リソース名をみてもなんとなく取得するデータはわかりそうですが、以下に簡易的に記載します。

channelTitle=チャンネルのタイトル

title=動画のタイトル

videoId=動画へアクセスするリンク

publishedAt=アップロードされた日時

また他に欲しい情報があれば、仕様に記載してるリソース種類を確認して取得するようにします。

⑤・・・データをセルに表示します。[配列に格納した値を表示する]に記載してます。

チャンネルIDを取得し配列に格納する

チャンネルIDを取得し配列に格納するメソッド

function GetChannelId(){
  
  //セルの先頭を設定
  var columnint = 2;
  var retsuint = 2;
  
  //ChannelIDシートを選択
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName('ChannelID');
  
  //最終行を取得
  var lastRow;
  lastRow = sheet.getLastRow();
  
  //配列を宣言
  var channelArray = [];
  
  //セルの先頭を取得
  var range = sheet.getRange(columnint,retsuint);
  
  var int = 0;
  //ChannelIDを取得
  for(;columnint <= lastRow; columnint++){
    channelArray[int] = sheet.getRange(columnint,retsuint).getValue();
    int++;
  }
  var URL = ArrayJoin(channelArray);
  
  return URL;
}

配列をURLと結合する

配列をURLと結合するメソッド

ここでの注意は、key=XXXXXXXXと記載してるところは自分のkeyを記載してください。

また、記事のタイトルにもある最新動画といっている部分はパラメータにある「order=date」で日付順にソートしてるだけです。

function ArrayJoin(channelArray){
  
  //URL固定値
  var Topurl = "https://www.googleapis.com/youtube/v3/search?part=id,snippet&maxResults=2&order=date&key=XXXXXXXX&channelId=";
  
  //channelArrayの要素数を検出
  var URL = [];
  //channelArrayの要素数分ループ
  //TopurlとchannelArrayを結合
  for(var urlint = 0;urlint <= channelArray.length - 1; urlint++){
    URL[urlint] = Topurl + channelArray[urlint]; 
  }
  
  return URL;
}

配列に格納した値を表示する

配列に格納した値を表示するメソッド

function ArrayDisplay(strChannelTitle,strVideoTile,strVideoURL,strReleaseDate,jsonint){
  
  //LatestSongListシートを選択
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName('LatestSongList');
  
  //最終行を取得
  var lastRow;
  lastRow = sheet.getLastRow();
  
  //変数を宣言
  var hairetuint = 0;
  
  for(var int = 0; int < jsonint; int++){
    //行番号
    for(var gyoint=lastRow + 1; gyoint<=lastRow + 3; gyoint++){
      //列番号
      for(var retsuint=2; retsuint<=5; retsuint++){
        
        //データをセルに表示していく
        switch(retsuint){
          case 2:
            //channelTitleをセルに表示
            sheet.getRange(gyoint,retsuint).setValue(strChannelTitle[hairetuint]);
            break;
            
          case 3:
            //titleをセルに表示
            sheet.getRange(gyoint,retsuint).setValue(strVideoTile[hairetuint]);
            break;
            
          case 4:
            //videoURLをセルに表示
            sheet.getRange(gyoint,retsuint).setValue(strVideoURL[hairetuint]);
            break;
            
          case 5:
            //ReleaseDateをセルに表示
            sheet.getRange(gyoint,retsuint).setValue(strReleaseDate[hairetuint]);
            break;
        }
        
      }
      hairetuint++;
    }
    //最終行を取得
    var lastRow;
    lastRow = sheet.getLastRow();
  }
}

セルを初期化する

セルを初期化するメソッド

function DeleteCell(){
  
  //LatestSongListシートを選択
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName('LatestSongList');
  
  //最終行を取得
  var lastRow;
  lastRow = sheet.getLastRow();
  
  //指定セルに値があるか検証
  if(sheet.getRange(7, 2).getValue()){
    
    //指定セルに値があった場合すべての内容を削除
    sheet.getRange(7,2,lastRow,5).clearContent();
    
  }
  
}

実行結果

上記のコードを実行してみた結果が以下です。ちゃんとデータが表示されることが確認できました。

パラメータで2つずつしか表示させてませんが、1チャンネルに対して50個とか表示できると思います。そうなるとクォーターの使用量ってやつがかなり消費されることになります。一日の使用量があるので、使いすぎるとAPIが実行できなくなります。注意が必要な部分ですね。

また、今の実装で「ChannelID」シートにチャンネルIDを追記していけばズラーッと一覧化ができます!

最後

はい、今回はデータを収集しセルに表示してみました。

罫線とか引いてない為、見づらい場合は罫線を引いてみたり表にしてみると見やすいと思います。

また、見返してみると変数の名前がナンセンスですね…。恥ずかしい変数名ですがまあいいでしょう!気にしないようにする。

とりあえず結果は出来たんですが、チャンネルIDがないものがあるので、ユーザ名からチャンネルIDに変換する実装を次回していきたいと思います。