我创建了一张表来保存我的加密资源。我使用我在youtube上找到的importJSON函数:(我已经更改了自己的帮助文本)
/**
* Imports JSON data to your spreadsheet Ex: IMPORTJSON("https://api.coinmarketcap.com/v2/ticker/1/?convert=EUR","data/quotes/EUR/price")
* @param url URL of your JSON data as string
* @param xpath simplified xpath as string
* @customfunction
*/
function IMPORTJSON(url,xpath){
try{
// /rates/EUR
var res = UrlFetchApp.fetch(url);
var content = res.getContentText();
var json = JSON.parse(content);
var patharray = xpath.split("/");
//Logger.log(patharray);
for(var i=0;i<patharray.length;i++){
json = json[patharray[i]];
}
//Logger.log(typeof(json));
if(typeof(json) === "undefined"){
return "Node Not Available";
} else if(typeof(json) === "object"){
var tempArr = [];
for(var obj in json){
tempArr.push([obj,json[obj]]);
}
return tempArr;
} else if(typeof(json) !== "object") {
return json;
}
}
catch(err){
return "Error getting data";
}
}
我使用此函数读取API: 这是我的一个剧本:
var btc_eur = IMPORTJSON("https://api.coinmarketcap.com/v2/ticker/1/?convert=EUR","data/quotes/EUR/price");
var btc_btc = IMPORTJSON("https://api.coinmarketcap.com/v2/ticker/1/?convert=BTC","data/quotes/BTC/price");
ss.getRange("B2").setValue([btc_eur]);
ss.getRange("H2").setValue([btc_btc]);
var bhc_eur = IMPORTJSON("https://api.coinmarketcap.com/v2/ticker/1831/?convert=EUR","data/quotes/EUR/price");
var bhc_btc = IMPORTJSON("https://api.coinmarketcap.com/v2/ticker/1831/?convert=BTC","data/quotes/BTC/price");
ss.getRange("B3").setValue([bhc_eur]);
ss.getRange("H3").setValue([bhc_btc]);
我得到的最后几天&#34;错误获取数据&#34;错误。当我开始手动编写它的脚本时。
我试过这个我在这里找到的代码:
function IMPORTJSON(url,xpath){
var res = UrlFetchApp.fetch(url);
var content = res.getContentText();
var json = JSON.parse(content);
var patharray = xpath.split("/");
var res = [];
for (var i in json[patharray[0]]) {
res.push(json[patharray[0]][i][patharray[1]]);
}
return res;
}
但是这给出了一个错误:TypeError:无法读取属性&#34;引号&#34;从null。我做错了什么?
答案 0 :(得分:1)
最大的问题是你的脚本调用API至少4次。当很少有用户这样做时,Google服务器调用API太多次了。
Coinmarketcap的API带宽有限。当任何客户端达到此限制时,API将返回HTTP error 429。 Google Scripts位于共享的Google服务器上,这意味着很多用户看起来都是Coinmarketcap API的客户端。
当API拒绝您的请求时,您的脚本将失败 - 错误消息对应于假定的错误(xpath无法在空变量中找到引号组件)。
这是无情的行为。请不要通过群发电话破坏API。
您可以立即从API加载数据,并为数据中的每个发现重新使用它。
我有类似的电子表格从Coinmarketcap API自动填写,你可以复制它:
我的脚本严格只针对整个运行时询问API一次,并为所有查询重用一个响应。
此外,您可以在代码中进行一些更改以节省资源:
从此更改IMPORTJSON
功能:
function IMPORTJSON(url,xpath){
var res = UrlFetchApp.fetch(url);
var content = res.getContentText();
var json = JSON.parse(content);
...
到此:
function IMPORTJSON(json, xpath) {
...
你可以改变代码的和rutime部分:
var res = UrlFetchApp.fetch("https://api.coinmarketcap.com/v2/ticker/1/?convert=EUR");
var content = res.getContentText();
var json = JSON.parse(content);
var btc_eur = IMPORTJSON(json,"data/quotes/EUR/price");
var btc_btc = IMPORTJSON(json,"data/quotes/BTC/price");
ss.getRange("B2").setValue([btc_eur]);
ss.getRange("H2").setValue([btc_btc]);
...
主要好处是:UrlFetchApp.fetch
只被调用一次。
是的,我知道,这段代码与你的1:1不一样。因为那只收到欧元而不是BTC的价格。自然地获取BTC和BTC之间的比较是不必要的,因为它总是1和其他值,您可以从EUR反应中进行数字计算 - 请不要滥用api进行此类查询。
答案 1 :(得分:0)
正如 Jakub 所说,主要问题是所有请求都被视为来自同一个 Google 服务器。
我认为更简单的一个解决方案是在中间放置一个代理服务器,这可以通过购买服务器并设置它(这非常复杂)或使用像 Proxycrawl 这样的服务来完成,其中包括一些免费请求和之后,除非您每月运行数千次查询,否则每月的费用应该不到 1 美元。
为此,您只需要编辑一行脚本:
var res = UrlFetchApp.fetch(url);
这一行,变成这样:
var res = UrlFetchApp.fetch(`https://api.proxycrawl.com/?token=YOUR_TOKEN&url=${encodeURIComponent(url)}`);
确保将 YOUR_TOKEN 替换为您的实际服务令牌
只是这个简单的更改将使请求永远不会失败,因为每个请求都将从不同的 IP 发送,而不是全部来自 Google。