Google Apps 脚本 returns 一个错误 "Limit Exceeded: URLFetch URL Length"

Google Apps Script returns an error "Limit Exceeded: URLFetch URL Length"

YouTube 数据 api v3 nextPageToken 太长 Google Apps 脚本 returns 错误 Limit Exceeded: URLFetch URL Length 当我尝试 UrlFetchApp.fetch("requesturl");

这是请求url www.googleapis.com/youtube/v3/commentThreads?key="+API_KEY+"&part=id&videoId="+ VIDEO_ID +"&order=relevance&textFormat="plaintext&pageToken=" + nextPageToken

代码

  var API_KEY = '***************************************';
  var VIDEO_ID = 'oG2Ka3nOVzM';
  var maxResults = 100 ; 
  var pageToken = ""; 
  var order = "relevance";
  var textFormat = "plaintext";
  url_commentthreads_1 = "https://www.googleapis.com/youtube/v3/commentThreads?key="+API_KEY+"&part=id&maxResults=100&videoId="+ VIDEO_ID +"&order="+ order +"&textFormat=" + textFormat + "&pageToken="
  var response_commentthreads_1 = UrlFetchApp.fetch(url_commentthreads_1);
  if (response_commentthreads_1.getResponseCode() != 200) {
    Logger.log("Error %s:", response_commentthreads_1);
    return;
  }
  var json_commentthreads_1 = JSON.parse(response_commentthreads_1.getContentText());
  var items = json_commentthreads_1['items'];
  var nextPageToken = json_commentthreads_1['nextPageToken'];
  Logger.log(nextPageToken);

  var length_1 = items.length;  
  var array_1 = [];
  for (var i = 0; i < length_1; i++) { //コメントIDの数だけIDの配列を作る
    array_1.push(items[i]['id'])
  }
  Logger.log(array_1);  

  while(nextPageToken != undefined){
    url_commentthreads = "https://www.googleapis.com/youtube/v3/commentThreads?key="+API_KEY+"&part=id&videoId="+ VIDEO_ID +"&order="+ order +"&textFormat=" + textFormat + "&pageToken=" + nextPageToken
    Logger.log(url_commentthreads);
    var response_commentthreads = UrlFetchApp.fetch(url_commentthreads); //This returns the error "Limit Exceeded: URLFetch URL Length."
    var json_commentthreads = JSON.parse(response_commentthreads.getContentText()); 
    var items_new = json_commentthreads['items'];
    var length_new = items_new.length; 
    Logger.log(length_new);    
    for (var i = 0; i < length_new; i++) { //コメントIDの数だけIDの配列を作る
      array_1.push(items_new[i]['id'])
    }
    var nextPageToken = json_commentthreads['nextPageToken'];
    Logger.log(nextPageToken);
  }

谁能帮助避免这个错误?

nextpagetokens 之一是这样的。 pageToken=QURTSl9pMFo0dE9oaEE0T2pHWEJYNGk2dkx4ZzZkYW5vc2xET0QyWk1wUUEwVGZ3YmF5NE4wUENzT2V5dFdwRDZJaVBJdFpHU3ZqRXhFcEFDWnd6YWJ3VmhDSkJVb3BqUEVxakVxeE5XZ2JmeGh6cnhfN2k1VmNZd3VGRWRFS1hvRG4zemZCeEl2ajU1RGVrYzE1LVNBZlJJMVUwUTFMMGV4VTE2X25VSDMwMnlZY1gwdFFXUl9DYnpuTUZwZnAyWGVnZ0lwNU9sYzNnOG5aQU1QRDRGdGhFbDdJZ2pVT0J5Tzg2dVVKbWw2NF93NTFuaUNmNThwT3o3blNNMkQwTlluTFBsWjNxamlpbk8wMnhiYXVuY28za282NWxPVHJYR3ZrLWRZWVVjWTduQ1c2NmEyQmtmS2Y0Z1g5NzJyRXJCM0VnN3pDdXRtaWt5X245Vm52Uy1oS0pSM2R5RHVqSlYxQXhkY3pLRE1idUdKN2wwaDFSVE9wNzNVek5wbG9DekhfbkRhOEVlSjRaSmJabUs1YVlvZ1VDbEhwVkUxdVMzOHJIQWxDcWtSc182MTBKUTBMdkNHZ0R3ZXFXamdyZGZIemZpMnlJRnBMQV84OXBsRFN0MGpvcG4td2xnZ1BpR3g2Q1hPZERnTTluMDlEN09IWTNvRDJ1TXMzbDQ1ZWlhQU5NalhrQUg2dnNhb21ibVZWbk9LX1JsZzF2dG1TVzZvbHZ0SDNNN3ZqSDVjZGJ2SGplQnpmbzBxU3h5bDc5eks5Y2ljWjBuaFZuUW5VWHdJVFJZTHJUVTZKbnJtc3R4ZkY2Zkh2Q0Y5Uzk5Y0NaU29EQVBQcWZfRDgweDdETEtWOEx6S2kxb1ZyYlNJOXVaYVlvQmxQT21HLUhWMm5rNWwzYjB3VFZzcXR4RmlkanlHbFlvU1NsUThBaVllYy1qNHRkbVlMNFJzTHR1dUNScUNFUXQ1eDRMQzRFQWR1bDhELVo3WDF3NzY3TkQtMzJjQThiRU0wX1lfamZYX1dEWWZPa2VEbW1yM1RWNVlVR2I4WHNnX0ZYeEF1RmFtcUk0TFFHZnhPbzBEa0dJWTMtWVYwRVZtRVFtdEl2b0RkSjZxSjVwdERBUjBxOTlEUXZGM1ZQbThua0tkdjk2U0MxRkFpcm5VYnR5NVI1dTNfS2N3Y1VSYm13b2I2XzdJU1hnLTM0NzRWZTVMeFJRWk4wMVJqbjF3QVV5M3J4WUd6a0hkM0QxYV9faVlfMUc4Sk5JMjJ0cXRYblRKbG50Ui0wcGwzSm1JQV9iUWpRemVaY0Rta1Z2WnVGYWtJS3plSXBfT3pVZ2p0cWJ0WEpzeVJqWVJIWkxRMV9uTVhqdTNBazJ6eTAtY3V5d2kzeTBnYUR0V3ZJVzFHYUZsSXBrcXVxX2dSM1N2TFB4U0lkNFl1Z2RhOTZLTHBqcld0ZHRzYWhDcVVzN0VkQ01fVGZSM0hNN085YktXelpKLUNmOG9jZ3NuTjRCdmVuQ3JCQjVBRVBmeFZKa0JJZVotaDVtQ1Vrb1gtNm9mMzJHWkt4ODJBcWpCd3RzamdJNzl4QkM5VzlCUUZNNjhmemtfeFhfYzQ5UG5uN1lCZjM0cmZXXzJtQmZhczVxSlVLaTdsc05fUkNQUGd0S1gyNm02UGV6NXcwUkc4dFBzVGdQbHRmRm5ic0t2bk5Rd0pDakVqb2c4bEdxUk9Db3RHUkpMT1picFN1blpjUTBfN1JXQ04ySTRhcTZIQmUwOG9PNW1DeGQ3WXRibnd3N2ZlaTZyYm9hcGpoUDM1YnkyelZUTnZMaG5FbDlfQlNSSGpXaGFtMm5uaXVEQmdHLVJYQTdZT2pLNUVuVHluX0NpRk1mV2FSQVBSZHAtWTFkSWVOZkl5eUhDU21kNE81QklNZTNLM3lSUGVoc0dYWA==

这个答案怎么样?请将此视为几个可能的答案之一。

问题:

从您的端点(包括查询参数)获得以下结果。

  1. "https://www.googleapis.com/youtube/v3/commentThreads?key="+API_KEY+"&part=id&maxResults=100&videoId="+ VIDEO_ID +"&order="+ order +"&textFormat=" + textFormat + "&pageToken="
    • 这是您正在使用的端点。
    • 使用上述端点时,nextPageToken的值长度为1832。
  2. "https://www.googleapis.com/youtube/v3/commentThreads?part=id&maxResults=100&videoId="+ VIDEO_ID +"&order="+ order
    • 删除了 textFormat 的一个参数。
    • 使用上述端点时,nextPageToken的值长度为1832。
  3. "https://www.googleapis.com/youtube/v3/commentThreads?part=id&maxResults=100&videoId="+ VIDEO_ID
    • 删除了 textFormatorder=relevance 的一个参数。
    • 使用上述端点时,nextPageToken的值长度为176。
    • 使用order=time时,nextPageToken的值长度为172。
  4. "https://www.googleapis.com/youtube/v3/commentThreads?part=id&maxResults=10&videoId="+ VIDEO_ID
    • 删除了 textFormatorder 的一个参数。并将 maxResults 减少到 10.
    • 使用上述端点时,nextPageToken的值长度为172。

从上面的结果发现,当使用order=relevance时,nextPageToken的值长度变长了。

而且在你的脚本中,URL 的长度似乎超过了 2 kbytes。我认为这样,您的脚本就会出错。

为了避免这种情况,下面的模式怎么样?

模式 1:

删除order=relevance的查询参数。

模式二:

减少 maxResults.

  • 当您的默认端点 maxResults 为 10、25 和 50 时,nextPageToken 的值长度分别为 328、580 和 1000。

模式 3:

使用高级 Google 服务而不是 UrlFetchApp。

  • 当使用高级 Google 服务的 YouTube 数据 API 时,我可以确认不会发生此类错误。不幸的是,我不确定高级 Google 服务的 YouTube 数据 API 的内部流程。所以我无法获得没有发生错误的原因。对此我深表歉意。

修改后的脚本:

在使用此脚本之前,please enable YouTube Data API at Advanced Google Service.

// var API_KEY = '***************************************';
var VIDEO_ID = 'oG2Ka3nOVzM';
var maxResults = 100 ; 
var pageToken = ""; 
var order = "relevance";
var textFormat = "plaintext";

// I added below script.
var json_commentthreads_1 = YouTube.CommentThreads.list("id", {maxResults: maxResults, videoId: VIDEO_ID, order: order, textFormat: textFormat});

var items = json_commentthreads_1['items'];
var nextPageToken = json_commentthreads_1['nextPageToken'];
Logger.log(nextPageToken);

var length_1 = items.length;  
var array_1 = [];
for (var i = 0; i < length_1; i++) { //Create an array of IDs for each comment ID
  array_1.push(items[i]['id'])
}
Logger.log(array_1);  

while(nextPageToken != undefined){

  // I added below script.
  var json_commentthreads = YouTube.CommentThreads.list("id", {maxResults: maxResults, videoId: VIDEO_ID, order: order, textFormat: textFormat, pageToken: nextPageToken});
  
  var items_new = json_commentthreads['items'];
  var length_new = items_new.length; 
  Logger.log(length_new);    
  for (var i = 0; i < length_new; i++) { //Create an array of IDs for each comment ID
    array_1.push(items_new[i]['id'])
  }
  var nextPageToken = json_commentthreads['nextPageToken'];
  Logger.log(nextPageToken);
}

参考文献:

更新时间:2020 年 11 月 30 日

在此模式中,stvar 的回答和评论反映到 OP 的脚本中。 GET 请求转换为 POST 请求。在这种情况下,无法使用 API 键。所以使用了访问令牌。现阶段发现page token可以直接使用

模式 4:

var API_KEY = '###';
var VIDEO_ID = 'oG2Ka3nOVzM';
var maxResults = 100 ; 
var pageToken = ""; 
var order = "relevance";
var textFormat = "plaintext";
var url_commentthreads_1 = "https://www.googleapis.com/youtube/v3/commentThreads?part=id&maxResults=100&videoId="+ VIDEO_ID +"&order="+ order +"&textFormat=" + textFormat + "&key=" + API_KEY + "&pageToken="
var response_commentthreads_1 = UrlFetchApp.fetch(url_commentthreads_1, {muteHttpExceptions: true, method: "get"});

if (response_commentthreads_1.getResponseCode() != 200) {
  Logger.log("Error %s:", response_commentthreads_1);
  return;
}
var json_commentthreads_1 = JSON.parse(response_commentthreads_1.getContentText());
var items = json_commentthreads_1['items'];
var nextPageToken = json_commentthreads_1['nextPageToken'];
Logger.log(nextPageToken);

var length_1 = items.length;  
var array_1 = [];
for (var i = 0; i < length_1; i++) {
  array_1.push(items[i]['id'])
}
Logger.log(array_1);  

while(nextPageToken != undefined){
  url_commentthreads = "https://www.googleapis.com/youtube/v3/commentThreads?part=id&maxResults=100&videoId="+ VIDEO_ID +"&order="+ order +"&textFormat=" + textFormat + "&key=" + API_KEY + "&pageToken=" + nextPageToken
  Logger.log(url_commentthreads);
  var response_commentthreads = UrlFetchApp.fetch(url_commentthreads, {method: "get"}); //This returns the error "Limit Exceeded: URLFetch URL Length."
  var json_commentthreads = JSON.parse(response_commentthreads.getContentText()); 
  var items_new = json_commentthreads['items'];
  var length_new = items_new.length; 
  Logger.log(length_new);    
  for (var i = 0; i < length_new; i++) {
    array_1.push(items_new[i]['id'])
  }
  var nextPageToken = json_commentthreads['nextPageToken'];
  Logger.log(nextPageToken);
}

您的问题源于 API 的一个已知问题,该问题不久前 在 Whosebug 上被发现。

我将总结发现的东西 -- Google 工作人员 confirmed 发现的东西。您可以阅读上面引用的 SO 线程上的所有详细信息。

  • 从 YouTube 的 CommentThreads.list 端点获取结果集在设计上有局限性,因为 API 中断,当 pageToken 变得太长时返回错误(长度的限制根本没有记录)。

  • 如果一个pageToken足够长,使得URL传递给API的长度超过2K,那么GET方法应替换为等效的 POST 一个。为了说服自己,看看 Google 自己的 public Python code。 Google.

    发布的任何其他客户端库的工作方式类似