Webサイトから情報を取得する④ Web API vol.1

通常、インターネットでWeb上の情報にアクセスするには、WebブラウザにURLを打ち込んで「これこれの情報が欲しい」とリクエストするわけですが、ブラウザを介さずにリクエストする方法もあります。
それが、Web API(Application Programing Interface)を使った方法です。
多くのサービスが、異なるアプリケーションやサービス間の連携を容易にし、お互いの情報や機能を外部から操作するためのインターフェースを用意してくれています。
ただ、API の操作は独特の設定や作法などがあるため、ブラウザでネットに繋ぐよりハードルが高いのも事実です。
GASが用意してくれているサービスを使えば、比較的容易にAPIに触れることができるので、チャレンジしてみましょう!

今回は、誰もが知ってる動画サイト、YouTubeの情報をYouTube Data APIを使って取得していきます。

YouTube Data APIを有効にする

まずスプレッドシートを1つ用意します。
拡張機能からコンテナバインドのApps Scriptを立ち上げましょう。
スクリプト名を「YouTube Data API」としておきます。

次に左メニューの「サービス」の➕ボタンをクリックします。

サービス一覧から「YouTube Data API」を選んで追加します。

「サービス」の下に「YouTube」と追加され、これでYouTube Data APIが有効になりました。
右の3点マーク、そして「ドキュメントを表示」をクリックします。

サンプルコードの実行

公式ドキュメントが開きます。
こちらに3種類のサンプルコードが掲載されています。
今回は、一番上の「キーワードで検索」のコードをコピーしましょう。
こちらのサンプルコード、searchByKeyword関数は、「犬に関する動画を25件検索し、動画の IDとタイトルをログに記録する」とのことです。
エディタにペーストして早速実行してみましょう!

初回実行すると承認が求められますので、承認します。
承認手順が分からない方は下の記事を参考にしてください。

実行ログを見ると、検索ワード「dogs」でヒットしたYouTube動画のIDとタイトルが見事取得できていることがわかります!
API便利❗️❤️

ここまでサクッとできてしまいましたね。
ただ、このままだとログ出力して終わってしまいますので、次に、少し手を加えて、取得した内容をスプレッドシートに展開させてみましょう。
えっ?APIの中身が分からない?
とりあえずスルーしましょうw

データをスプレッドシートに展開

サンプルコードの一部を下図のように書き換えました。
新たに、youtubeDataToSS関数を作りました。
この関数内でsearchByKeyword関数を実行し、受け取ったデータをスプレッドシートに渡して展開しています。

では、youtubeDataToSS関数を実行してみましょう。
検索ワードを日本語で「犬」としています。

無事、スプレッドシートに展開できました!
「犬」関連の動画のIDとタイトルが25件取得できています!

検索ワードを変数で取得する

取得データをスプレッドシートで扱えるようになったので、少しアプリっぽくなりました。
次は、現在コード内に直書きしている検索ワードを変数で受け取れるようにして、もっとアプリっぽくしてみましょう。
まずは文字入力GUIを用意して、入力された値を変数に格納すればOKです。
今回、GUIはスプレッドシートでサクッと作っちゃいます。

シートにGUIを作る

「検索」というシートに、図のようなイメージで検索ワード入力欄と検索実行ボタンを用意します。
このサンプルでは、B3セルを入力欄としました。

検索ボタンは、メニューの「挿入」→「図形描画」から作図します。
ボタン右上の3点マークから「スクリプトの割り当て」をクリックします。

ボタンクリック時に実行したい関数名を入力して確定します。
今回は、「youtubeDataToSS」です。

コードの更新

searchByKeyword関数は、図のように3カ所のコードを追加、変更します。
1. B3セルに入力された検索ワードを変数queryに格納
2. qパラメータの値にqueryをセット
3. 関数のreturnを配列としてqueryを加える

youtubeDataToSS関数は図のように変更します。
returnされたdataとqueryを受け取って同名の変数に格納します。
queryと同名のシートにdataを上書きします。
同名のシートがない場合は、新たに作成してdataを展開します。

では、うまくいくか試してみましょう。
「検索」シートの検索ワード欄に「大谷翔平」と入力し、検索ボタンを押します。

はい。うまくいきました!
このワードで初めて検索するので、「大谷翔平」というシートが追加されて、そこに動画のIDとタイトルが25件取得されました。
(この日は、記念すべき30号、150mの超特大ホームランを打った日ですね。おめでとうございます!)

他のワードでも検索してみましょう。
YouTube検索アプリ、ほぼ完成です!

動画のURLリンクが欲しい

なんてったって動画ですから、やっぱり観たいですよね。
スプレッドシート展開時に動画のURLリンクが貼られていたら便利なんですけど、、、
ただ、APIプロパティの中に動画IDはあるんですが、動画URLはないんですね。
でも、大丈夫です。
IDにドメインを追加してあげればURLになっちゃいますから!

というわけで、YouTube動画のURLは、"ドメイン + 動画ID"という構成になっていますので、ドメイン部分の「https://www.youtube.com/watch?v=」をコードに追加します。

これで試してみると、、、

動画URLが取得できました!
これで動画視聴もワンクリックで可能です!

完成コード

function searchByKeyword() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('検索');
  const query = sheet.getRange('B3').getValue();
  try {
    const results = YouTube.Search.list('id,snippet', {
      q: query,
      maxResults: 25,
      type: 'video'
    });
    if (results === null) {
      console.log('Unable to search videos');
      return;
    }
    const data = [];
    results.items.forEach(item => {
      const rowData = ['https://www.youtube.com/watch?v='+item.id.videoId, item.snippet.title];
      data.push(rowData);
    });
    return [data, query];

  } catch (err) {
    // TODO (developer) - Handle exceptions from Youtube API
    console.log('Failed with an error %s', err.message);
  }
}

function youtubeDataToSS() {
  const [data, query] = searchByKeyword();

  const ss = SpreadsheetApp.getActiveSpreadsheet();
  let sheet = ss.getSheetByName(query);
  if (sheet === null) {
    sheet = ss.insertSheet(query);
  }
  sheet.getRange(1, 1, data.length, data[0].length).setValues(data);
}

コード解説ざっくりと

最後になりましたが、コードのポイント部分だけ押さえておきましょう。

ゴールから考える

APIを使ってどんな情報が欲しいのか、つまり何をレスポンスで返して欲しいのか、とゴールから考えてみると分かりやすいです。
今回は検索した動画のIDとタイトルを取得するのがゴールでした。

では、その値はどこで得られるのか?(どのプロパティにあるのか?)というと、
IDはvideoIdプロパティ、タイトルはtitleプロパティにその値があります。(完成コードの16行目)

ただ、ダイレクトにこれらのプロパティにアクセスできるわけではなく、コードをご覧いただくと分かるように、レスポンス本体はオブジェクトの階層構造(入れ子)になっていて、videoIdプロパティはidプロパティに、titleプロパティはsnippetプロパティに、そして双方はitemsプロパティに属しています。これらの階層をドット(.)で辿っていくことで最終ゴールに到達できるわけです。

そしてさらに遡ると、これらの情報は全てYouTube Data APIのSearchというリソースに含まれています。
このようにゴールから考えることで、ではその結果を得るためには、そもそもどのようにリクエストすれば良いのかと考えることができ、リクエストのかたちが見えてきます。

APIリクエストの構成

サービスリソースメソッド引数(part/必須)引数(オプション)
YouTubeSearchlistid, snippetq, maxResults, type

5行目からのHTTPリクエストコードの構成です。
該当の公式ドキュメントにリンクされていますので、ぜひそちらもご覧ください。取得できる全てのプロパティとその階層構造が確認できます。

  1. Searchリソースではlistメソッドのみサポートされています。
  2. listメソッドでリクエストする場合、part(id, snippet)と呼ばれるパラメータが必須引数です。
    取得したいプロパティ(videoId, title)の上位プロパティを必ず引数で渡さなければなりません。
  3. オプション引数でレスポンスをフィルタリングできます。
q検索ワード
maxResults検索結果最大数0以上50以下の値を指定可能。デフォルト値は5
type取得するリソースタイプを制限デフォルト値は video, channel, playlist
その他order: viewCountとすると再生回数の多い順に並べる など

ぜひ、公式ドキュメントを研究して、APIを楽しんでください!
今回、try〜catch、forEachやアロー関数についての説明は割愛しました。

シリーズ目次:Webサイトから情報を取得する

  1. Webサイトから情報を取得する① ファイルのダウンロード
  2. Webサイトから情報を取得する② スプレッドシートにインポート
  3. Webサイトから情報を取得する③ スクレイピング
  4. Webサイトから情報を取得する④ Web API vol.1
  5. Webサイトから情報を取得する⑤ Web API vol.2