我正在尝试自动收集Google电子表格中Youtube视频的统计信息。为此,我在电子表格脚本编辑器中将代码与getYoutubeViews函数以及GETURL,linkURL函数等配合使用。
这是getYoutubeViews函数示例
function getYoutubeViews(videoId){
var url = "https://www.googleapis.com/youtube/v3/videos?part=statistics&id=" + videoId;
url = url + "&key=mykey";
//Utilities.sleep(Math.random(15000))
var videoListResponse = UrlFetchApp.fetch(url);
var json = JSON.parse(videoListResponse.getContentText());
return json["items"][0]["statistics"]["viewCount"];
}
function GETURL(input) {
var range = SpreadsheetApp.getActiveSheet().getRange(input);
var url = /"(.*?)"/.exec(range.getFormulaR1C1())[1];
return url;
}
我遇到两个问题。
当用户加载表时,脚本开始工作。由于表中的视频数超过600个,因此这将启动大量处理。这将导致错误:“服务在短时间内被调用太多次:exec qps”。
但是用Utilities.sleep修复它没有意义,因为还有第二个问题。经过3-4个小时的工作并定期刷新表格,Google的10,000点的API密钥配额就结束了。
我试图最小化列表上的功能和动作,并使用Utilities.sleep来避免此错误:
Service invoked too many times in a short time: exec qps.
Try Utilities.sleep(1000) between calls. (строка 0).
但这似乎无助于解决配额问题。
在我看来,我可以某种方式将数据保存在单元格中,仅在更新数据时才激活功能。我试图将更改触发器用于这些目的,但是我做错了或没有帮助。
第二个假设是,有可能以某种方式保存先前的数据,这样即使发生脚本错误,单元格中也会有一些数据。但是我不知道该怎么办。
答案 0 :(得分:1)
避免使用自定义函数(每次都会发出所有请求)的一种方法是使用onOpen()触发器添加菜单[1],单击该菜单即可运行getYoutubeViews()函数。此功能将发出请求,并将响应数据(观看次数)插入电子表格中。它将从B列(从第二行开始)获取videoId,并在D列中设置观看次数。我设置了“ If”条件,以便仅对空视图单元格发出请求(更新值)。
要处理电子表格上的数据,我使用了SpreadsheetApp类[2]
function onOpen() {
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.createMenu('Actions')
.addItem('Add views', 'getYoutubeViews')
.addToUi();
}
function getYoutubeViews(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet2");
var videoIdArray = sheet.getRange(2, 2, sheet.getLastRow()-1, 1).getValues();
var views = sheet.getRange(2, 4, sheet.getLastRow()-1, 1);
for(var i=0; i<videoIdArray.length ; i++) {
var videoId = videoIdArray[i][0];
var viewsCell = sheet.getRange(2 + i, 4);
if(viewsCell.getValue() == "") {
var url = "https://www.googleapis.com/youtube/v3/videos?part=statistics&id=" + videoId;
url = url + "&key=AAIzaSyAUjC5AchndLg9BRIrRBYKLuKf-fFkMC9M";
var options = {
'muteHttpExceptions' : true,
'headers': {
'Authorization': 'Bearer ' + ScriptApp.getOAuthToken(),
}
};
var videoListResponse = UrlFetchApp.fetch(url, options);
var json = JSON.parse(videoListResponse.getContentText());
Logger.log(json)
var views = json["items"][0]["statistics"]["viewCount"];
viewsCell.setValue(views);
}
}
}
您不能使用onEdit()函数直接运行代码,因为触发器有限制[3],其中有一个说:
他们无法访问需要授权的服务。
UrlFetchApp.fetch()是一项需要用户授权的服务。
[1] https://developers.google.com/apps-script/guides/menus
[2] https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet-app
[3] https://developers.google.com/apps-script/guides/triggers/#restrictions