LoginSignup
3
3

More than 3 years have passed since last update.

【覚書】YouTube Data API で特定のチャンネルの動画情報を全取得

Last updated at Posted at 2020-12-01

50 個まではこれでいける

const API_KEY = "";

const getYouTube = async (api, query, cooldown = 3000) => {
  await new Promise((r) => setTimeout(r, cooldown));
  return await (
    await fetch(
      `https://www.googleapis.com/youtube/v3/${api}${Object.entries(
        query
      ).reduce((p, [k, v]) => `${p}&${k}=${v}`, `?key=${API_KEY}`)}`
    )
  ).json();
};

const getVideos = async (channelId, pageToken = "") => {
  const playlistId = (
    await getYouTube("channels", {
      part: "contentDetails",
      id: channelId,
    })
  ).items[0].contentDetails.relatedPlaylists.uploads;
  return await getYouTube("playlistItems", {
    part: "snippet",
    maxResults: 50,
    playlistId,
    pageToken,
  });
};

getVideos(
  // https://www.youtube.com/channel/{これ}
  "UCsLiV4WJfkTEHH0b9PmRklw"
).then(console.log);

チャンネル動画だけが入ったプレイリストを取得してきて、その動画を取得する。

サーバー負荷とかを考慮して、クールダウン時間を設定できるようにしてある。

動画数は一度のリクエストでは 50 個までなので、
本当に全部取りたいなら nextPageToken を使って適宜実装する必要がある。

というわけで、全部とる

const getAllVideos = async (channelId) => {
  let [all, token] = [[]];
  while (1) {
    const { items, nextPageToken } = await getVideos(channelId, token);
    all = [...all, ...items];
    if (!nextPageToken) break;
    token = nextPageToken;
  }
  return all;
};

getAllVideos(
  // https://www.youtube.com/channel/{これ}
  "UCkvvFbRyfvENnl_G8YHuriQ"
).then(console.log);

これで根こそぎ取ってくれる。

気づいたこと

どうも、チャンネル ID の prefix がUCになっている場合、
プレイリスト ID はチャンネル ID の prefix をUUにするだけでいいらしい。

https://www.youtube.com/channel/UCQbL0aAYEmzAbvgBn2PAy4A
      ↓
U C QbL0aAYEmzAbvgBn2PAy4A
      ↓
U U QbL0aAYEmzAbvgBn2PAy4A
      ↓
https://www.youtube.com/playlist?list=UUQbL0aAYEmzAbvgBn2PAy4A

だからこれでもいけちゃうっぽい

const getVideos = async (channelId, pageToken = "") => {
  const playlistId = channelId.replace(/^UC/, "UU"); // <--
  return await getYouTube("playlistItems", {
    part: "snippet",
    maxResults: 50,
    playlistId,
    pageToken,
  });
};

こっちのほうがシンプルかもね。

Node.js でデモコードを試す場合の注意点

Node.js では fetch が使えません。
なので、素直に axios や node-fetch を使うなり、deno を使うなりしてください。

面倒くさい人はこれを使えばとりあえず動くんじゃない(適当)

const fetch = (url) =>
  new Promise((resolve, reject) => {
    const req = require("https").get(url, (res) => {
      let buffer = "";
      res.on("data", (chunk) => (buffer += chunk));
      res.on("end", () => resolve({ json: () => JSON.parse(buffer) }));
    });
    req.on("error", reject);
    req.end();
  });
3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3