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.
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 retrievevideoId
,title
, andpublishedAt
. And also, you want to retrieveviewCount
andlikeCount
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 useYouTube.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
, andpublishedAt
are retrieved usingarrSearchItems
withYouTube.Search.list
. And, the values ofviewCount
andlikeCount
are retrieved using the retrieved video IDs withYouTube.Videos.list
. And, the retrieved values are put on the sheet.