如何通过应用程序脚本在 Google 表格上获取超过 50 条记录?

How to get more than 50 records on Google Sheets through apps script?

我正在尝试收集 YouTube 元数据。但是,我无法分页。我只得到 50 条记录,但我想得到尽可能多的实例。

如何获得更多结果?

到目前为止这是我的代码。

function YoutubeScraper2() {
  var search = YouTube.Search.list("snippet, id", { 
    q: "pizza", 
    maxResults: 50 
  });
    var last_row = 0;
    var spreadSheet = SpreadsheetApp.getActiveSpreadsheet()
    var activeSheet = spreadSheet.getActiveSheet();

    for (var i = 0; i < search.items.length; i++){
        var results = search.items.map((item) => [item.id.channelId, item.id.videoId, item.snippet.title, item.snippet.publishedAt, item.snippet.thumbnails.default.url]);
        
        // Retrieve channel IDs and video IDs.
        var {channelIds, videoIds} = results.reduce((o, [channelId, videoId]) => {
          o.channelIds.push(channelId);
          o.videoIds.push(videoId);
          return o;
        }, {channelIds: [], videoIds: []});

        // Retrieve YouTube.Videos.list.
        var videoList = YouTube.Videos.list("statistics", {id: videoIds.join(",")});
        var videoStats = videoList.items.map((item) => [item.id, item.statistics.viewCount, item.statistics.likeCount, item.statistics.dislikeCount]).reduce((o, [id, ...v]) => Object.assign(o, {[id]: v}), {});
      

        // Retrieve YouTube.Channels.list
        var channelList = YouTube.Channels.list("statistics", { id: channelIds.join(",") });
        var channelStats = channelList.items.map((item) => [item.id, item.statistics.viewCount, item.statistics.subscriberCount]).reduce((o, [id, ...v]) => Object.assign(o, {[id]: v}), {});

        // Create an array for putting values and put the values to Spreadsheet.
        results = results.map(e => channelStats[e[0]] ? e.concat(channelStats[e[0]]) : e.concat(Array(2).fill("")));
        results = results.map(e => videoStats[e[1]] ? e.concat(videoStats[e[1]]) : e.concat(Array(3).fill("")));
        
        
        last_row = activeSheet.getLastRow() + 1;
        activeSheet.getRange(1, 1, results.length, results[0].length).setValues(results);
        last_row++;
    }
}

我相信你的目标如下。

  • 您想通过修改脚本来检索超过 50 个项目。

修改点:

  • 在这种情况下,我认为需要使用pageToken来检索数据。
  • 并且,在YouTube.Videos.listYouTube.Channels.list,50个id可以用于一次API调用。所以这些方法需要多次请求

当以上几点反映到你的脚本中,就会变成下面这样。

修改后的脚本:

function YoutubeScraper2() {
  var spreadSheet = SpreadsheetApp.getActiveSpreadsheet()
  var activeSheet = spreadSheet.getActiveSheet();
  var numberOfData = 200; // When 0 is set, all values are retrieved.

  // Retrieve YouTube.Search.list.
  var data = [];
  var pageToken = "";
  do {
    var search = YouTube.Search.list("snippet", { q: "pizza", maxResults: 50, pageToken: pageToken });
    data = data.concat(search.items);
    pageToken = search.nextPageToken;
    if (numberOfData != 0 && data.length > numberOfData) break;
  } while (pageToken);
  if (numberOfData != 0) data = data.splice(0, numberOfData);

  var results = data.map((item) => [item.snippet.channelId, item.id.videoId, item.snippet.title, item.snippet.publishedAt, item.snippet.thumbnails.default.url]);

  // Retrieve channel IDs and video IDs.
  var { channelIds, videoIds } = results.reduce((o, [channelId, videoId]) => {
    o.channelIds.push(channelId);
    o.videoIds.push(videoId);
    return o;
  }, { channelIds: [], videoIds: [] });

  // Retrieve YouTube.Videos.list.
  var videoList = [];
  while (videoIds.length > 0) {
    var temp = YouTube.Videos.list("statistics", { id: videoIds.splice(0, 50).join(",") });
    videoList = videoList.concat(temp.items);
  }
  var videoStats = videoList.map((item) => [item.id, item.statistics.viewCount, item.statistics.likeCount, item.statistics.dislikeCount]).reduce((o, [id, ...v]) => Object.assign(o, { [id]: v }), {});

  // Retrieve YouTube.Channels.list
  var channelList = [];
  while (channelIds.length > 0) {
    var temp = YouTube.Channels.list("statistics", { id: channelIds.splice(0, 50).join(",") });
    channelList = channelList.concat(temp.items);
  }
  var channelStats = channelList.map((item) => [item.id, item.statistics.viewCount, item.statistics.subscriberCount]).reduce((o, [id, ...v]) => Object.assign(o, { [id]: v }), {});

  // Create an array for putting values and put the values to Spreadsheet.
  results = results.map(e => channelStats[e[0]] ? e.concat(channelStats[e[0]]) : e.concat(Array(2).fill("")));
  results = results.map(e => videoStats[e[1]] ? e.concat(videoStats[e[1]]) : e.concat(Array(3).fill("")));
  var header = ["channelId", "videoId", "title", "publishedAt", "thumbnails", "viewCount", "subscriberCount", "viewCount", "likeCount", "dislikeCount"];
  results.unshift(header);
  activeSheet.getRange(1, 1, results.length, results[0].length).setValues(results);
}
  • 在此脚本中,使用var numberOfData = 200;,您可以检索要检索的数字的值。使用 var numberOfData = 0; 时,将检索所有可以使用 YouTube.Search.list 检索的值。
  • 在我的测试中,当var numberOfData = 0;用于上述脚本时,获得了707个值。

参考文献: