You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Apps Script urlfetch调用超限与执行超时问题咨询

TRIVIA接口批量查询限流问题修复方案

问题根因

  • 原代码使用UrlFetchApp.fetchAll一次性并发所有请求,短时间请求量触发Google Apps Script的UrlFetch服务限流,同时目标站点triviapw自身也有接口访问频率限制
  • 此前修改版本出现「无效请求」是因为请求参数格式和测试通过的单请求版本不一致,出现「超出最大执行时间」是因为全量串行请求加长等待,总耗时超过Apps Script单次执行6分钟的上限
  • 单请求可正常运行,说明接口本身、参数逻辑没有问题,核心是平衡请求频率和执行时长

修复逻辑

  • 采用小批量并发+批次间限流的模式:每次发少量并发请求,批次间加1秒以上间隔,既不触发限流规则,也比单条串行请求效率高,避免超时
  • 请求参数完全对齐单请求测试通过的格式,杜绝无效请求
  • 提前过滤A列ID为空的无效行,减少不必要的请求消耗
  • 所有结果收集完成后一次性写入表格,减少表格API调用,压缩总执行时长

可直接运行的修复代码

function myTrivia() {
  const f = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('TRIVIA');
  // 配置项:可根据实际限流情况调整
  const BATCH_SIZE = 8; // 每批并发请求数,触发限流就调小(最小为1)
  const REQ_INTERVAL = 1200; // 批次间等待毫秒数,留200ms冗余避免边界触发限流
  const MAX_EXE_TIME = 300000; // 单次执行最大安全时长5分钟,留1分钟余量写数据
  const startTime = new Date().getTime();

  // 初始化日期
  const today = new Date();
  const data = Utilities.formatDate(today, "GMT-03:00", "yyyy/MM/dd");
  f.getRange('F1').setValue(data);
  const serverName = f.getRange('G1').getValue();

  // 读取有效数据,过滤空ID行
  const allData = f.getDataRange().getValues();
  const [header, ...rows] = allData;
  const validRows = rows.filter(row => row[0] && String(row[0]).trim() !== '');
  const totalCount = validRows.length;
  const allResults = [];
  const url = 'https://triviapw.com.br/cotacao/api/item/';

  // 分批处理请求
  for (let i = 0; i < totalCount; i += BATCH_SIZE) {
    // 超时判断:如果剩余时间不足以处理下一批+写数据,提前终止(可配合触发器续跑)
    if (new Date().getTime() - startTime > MAX_EXE_TIME) {
      console.log(`执行时长接近上限,已处理${i}条,剩余${totalCount - i}条请配合时间驱动触发器续跑`);
      break;
    }
    // 构造当前批次的请求,参数完全对齐单请求测试版本
    const batchRows = validRows.slice(i, i + BATCH_SIZE);
    const batchReqs = batchRows.map(([itemId]) => ({
      url: url,
      method: "post",
      payload: {
        id: itemId,
        date: data,
        server: serverName
      },
      muteHttpExceptions: true
    }));
    // 执行当前批次请求
    const batchRes = UrlFetchApp.fetchAll(batchReqs);
    // 解析当前批次结果
    batchRes.forEach(res => {
      const resText = res.getContentText();
      if (res.getResponseCode() === 200 && resText !== "Requisição inválida") {
        const obj = JSON.parse(resText);
        allResults.push([obj.nome, obj.venda, obj.compra]);
      } else {
        allResults.push(Array(3).fill(""));
      }
    });
    // 非最后一批次时等待限流间隔
    if (i + BATCH_SIZE < totalCount) {
      Utilities.sleep(REQ_INTERVAL);
    }
  }

  // 一次性写入所有结果
  if (allResults.length > 0) {
    f.getRange(2, 2, allResults.length, 3).setValues(allResults);
  }
}

调优说明

  • 如果运行仍然触发urlfetch限流错误,将BATCH_SIZE调小至3-5,或将REQ_INTERVAL调整为1500-2000
  • 如果表格数据量超过300条,可搭配Apps Script时间驱动触发器,设置每5分钟运行一次,每次记录上次处理到的行号续跑,完全规避执行时长限制
  • 运行前确认F1日期格式、G1服务器参数和单请求测试时的取值完全一致,避免参数错误导致的无效请求

内容的提问来源于stack exchange,提问作者Wagner Vaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 01:39:17