Home > Blockchain >  Apps script: Does YouTube.Videos.list cap statistics results to 50 records?
Apps script: Does YouTube.Videos.list cap statistics results to 50 records?

Time:09-18

I would like to get YouTube data for a few anime titles. For each title I put in the query, I would like to retrieve 100 records.

I've used the pageToken in the parameters but I keep getting the error in the below image. I only get this error when I put maxResults : 50 in the for loop and while loop. When the maxResults parameter is less than 50 for both loops, its fine.

I've observed that the script throws an error when the total records that would be outputted for each anime title exceeds 50.

enter image description here

I don't understand why this error shows up because I thought the page tokens were to allow users to get more than 50 results, no?

Below is my code. Any help would be massively appreciated!

function youTubeData() {

  var ss = SpreadsheetApp.openById(<your sheet ID>);
  var activeSheet = ss.getSheetByName("YouTube Results");

  activeSheet.getRange("A2:G").clear(); // clear old data

  let executionTime = Utilities.formatDate(new Date(), "GMT 1", "yyyy/MM/dd HH:mm:ss");

  var arrSearchItems = ["attack on titan", "mob psycho 100", "demon slayer", "vinland saga"];

  for (let i = 0; i < arrSearchItems.length; i  ) {

    if(i>0) {break;} // for testing purposes only display Attack on Titan results

    var query = arrSearchItems[i];

    Logger.log((i 1)   ') '    query.toUpperCase())

    var videos = YouTube.Search.list('snippet', {
      q : query,
      type : 'video',
      maxResults : 50,
      order : "viewCount",
    });

    var allVideos = videos.items;

    var iteration = 1;

    while (videos.nextPageToken && iteration == 1 /* only return one extra page of youtube results - we only want 100 records for each anime */) {

      Logger.log('iteration = '   iteration)

      var videos = YouTube.Search.list('snippet', {
        q : query,
        type : 'video',
        maxResults : 50,
        order : "viewCount",
        pageToken : videos.nextPageToken,
      });

      iteration = iteration   1;

      allVideos = allVideos.concat(videos.items);    

    };

    var modRes = allVideos.map( function (v) { return [query.toUpperCase(), 'https://youtu.be/'   v.id.videoId, v.snippet.title, v.snippet.publishedAt]; } );

    var ids = modRes.map( function (res) { return res[1].split("/")[3]; }); // get ID of videos in modRes

    var stats = YouTube.Videos.list("statistics", {'id' : ids}); // get the stats for each video

    // build the video stats array
    var vidsStats = stats.items.map ( function (res) { return [res.statistics.viewCount, res.statistics.likeCount, executionTime] } );

    var rowStart = activeSheet.getLastRow()   1 // row start for the next search query when outputting to GSheets

    // output YouTube data to GSheets
    activeSheet.getRange(rowStart, 1, modRes.length, modRes[0].length).setValues(modRes);
    activeSheet.getRange(rowStart, 5, vidsStats.length, vidsStats[0].length).setValues(vidsStats);

  }

}

CodePudding user response:

According to the documentation the max number of results you can set is 50.

Here's a direct quote:

The maxResults parameter specifies the maximum number of items that should be returned in the result set.

Note: This parameter is supported for use in conjunction with the myRating parameter, but it is not supported for use in conjunction with the id parameter. Acceptable values are 1 to 50, inclusive. The default value is 5.

CodePudding user response:

I would consider restructuring the first part of your code like this:

  const ss = SpreadsheetApp.openById("ssid");
  const sh = ss.getSheetByName("YouTube Results");
  sh.getRange("A2:G"   sh.getLastRow()).clear();
  const executionTime = Utilities.formatDate(new Date(), "GMT 1", "yyyy/MM/dd HH:mm:ss");
  const sItems = ["attack on titan", "mob psycho 100", "demon slayer", "vinland saga"];
  for (let i = 0; i < sItems.length; i  ) {
    let query = sItems[i];
    let allVideos = [];
    let ptkn = '';
    do {
      let options = { q: query, type: 'video', maxResults: 50, order: "viewCount", pageToken: ptkn }
      let videos = YouTube.Search.list('snippet', options);
      ptkn = videos.nextPageToken;
      allVideos = allVideos.concat(videos.items);
    } while (ptkn)

CodePudding user response:

I believe your goal is as follows.

  • You want to search the values from arrSearchItems and retrieve videoId, title, and publishedAt. And also, you want to retrieve viewCount and likeCount from each video ID.
  • You want to retrieve the number of 100 from each value of arrSearchItems.

Modification points:

  • In your script, at 1st while loop, the length of allVideos is 100. And, 100 IDs are retrieved from the values. Using this IDs, you use YouTube.Videos.list("statistics", {'id' : ids}). In this case, there is the maximum number of IDs for {'id' : ids}. It's 50. The reason for your issue is due to this. This has already been mentioned in TheAddonDepot's answer. Ref
  • In your script, 2 setValues are used in a loop. In this case, the process cost will be high. Ref
  • In order to use pageToken, these threads might be useful. Ref1 and Ref2

When these points are reflected in your script, how about the following modification?

Modified script:

function youTubeData() {
  var ss = SpreadsheetApp.openById("<your sheet ID>"); // Please set your Spreadsheet ID.
  var activeSheet = ss.getSheetByName("YouTube Results");
  activeSheet.getRange("A2:G").clear();
  let executionTime = Utilities.formatDate(new Date(), "GMT 1", "yyyy/MM/dd HH:mm:ss");
  var arrSearchItems = ["attack on titan", "mob psycho 100", "demon slayer", "vinland saga"];

  // I modified below script.
  var values = arrSearchItems.flatMap(query => {
    var pageToken = "";
    var ar = [];
    do {
      var videos = YouTube.Search.list('snippet', { q: query, type: 'video', maxResults: 50, order: "viewCount", pageToken, fields: "nextPageToken,items(id(videoId),snippet(title,publishedAt))" });
      if (videos.items.length > 0) {
        var { v1, ids } = videos.items.reduce((o, { id, snippet }) => {
          o.v1.push([query.toUpperCase(), `https://youtu.be/${id.videoId}`, snippet.title, snippet.publishedAt]);
          o.ids.push(id.videoId);
          return o;
        }, { v1: [], ids: [] });
        var v = YouTube.Videos.list("statistics", { 'id': ids }).items.map(({ statistics }, i) => [...v1[i], statistics.viewCount, statistics.likeCount, executionTime]);
        ar = [...ar, ...v];
      }
      pageToken = videos.nextPageToken;
    } while (pageToken && ar.length < 100);
    return ar;
  });
  activeSheet.getRange(1, 1, values.length, values[0].length).setValues(values);
}
  • When this script is run, the values of videoId, title, and publishedAt are retrieved using arrSearchItems with YouTube.Search.list. And, the values of viewCount and likeCount are retrieved using the retrieved video IDs with YouTube.Videos.list. And, the retrieved values are put on the sheet.

References:

  • Related