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

Apps Script爬虫脚本性能优化及运行时限制突破咨询

Buff163爬虫脚本优化与Apps Script配额问题解答

1. 代码优化方案

原代码的核心性能瓶颈在于单次请求+单次写入的循环模式,以及低效的字符串解析方式,以下是具体优化点:

  • 改用批量请求(UrlFetchApp.fetchAll):循环单次请求会产生大量网络开销,fetchAll可一次性发送多个请求,大幅减少请求耗时。
  • 解析JSON而非字符串截取:原代码通过search/slice提取数据易出错且效率低,直接将响应转为JSON对象访问属性更高效可靠。
  • 批量写入电子表格:每次调用appendRow都会触发电子表格同步刷新,是极耗时操作。应将所有待写入数据收集到数组中,最后一次性用setValues写入。
  • 减少重复的电子表格对象调用:避免在循环/子函数中重复获取Spreadsheet和Sheet对象,提前获取一次即可。

优化后的示例代码:

function scrapeBuff163() {
  const scriptProps = PropertiesService.getScriptProperties();
  // 从脚本属性获取上次处理到的索引,默认从33858开始
  let startIndex = parseInt(scriptProps.getProperty('lastProcessedIndex')) || 33858;
  const endIndex = 60000;
  // 每次批量处理的数量,根据6分钟运行时调整,比如每次处理500条
  const batchSize = 500;
  const currentEnd = Math.min(startIndex + batchSize - 1, endIndex);
  
  // 构建批量请求的URL数组
  const urls = [];
  for (let i = startIndex; i <= currentEnd; i++) {
    urls.push(`https://buff.163.com/api/market/goods/sell_order?game=csgo&goods_id=${i}`);
  }
  
  // 批量发送请求
  const responses = UrlFetchApp.fetchAll(urls.map(url => ({
    url: url,
    muteHttpExceptions: true
  })));
  
  // 收集待写入的数据
  const dataToWrite = [];
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheetByName("Buff163");
  
  for (let i = 0; i < responses.length; i++) {
    const response = responses[i];
    const content = response.getContentText();
    if (content.length >= 1500) {
      try {
        const json = JSON.parse(content);
        if (json.data && json.data.goods_id && json.data.market_hash_name) {
          dataToWrite.push([json.data.goods_id, json.data.market_hash_name]);
        }
      } catch (e) {
        // 解析失败时跳过,避免中断整个流程
        console.log(`解析goods_id=${startIndex + i}失败: ${e.message}`);
      }
    }
  }
  
  // 批量写入数据
  if (dataToWrite.length > 0) {
    const lastRow = sheet.getLastRow();
    sheet.getRange(lastRow + 1, 1, dataToWrite.length, 2).setValues(dataToWrite);
  }
  
  // 更新脚本属性,记录当前处理到的索引
  scriptProps.setProperty('lastProcessedIndex', currentEnd + 1);
  
  // 如果还没处理完,触发下一次运行
  if (currentEnd < endIndex) {
    ScriptApp.newTrigger('scrapeBuff163')
      .timeBased()
      .after(1 * 60 * 1000) // 1分钟后运行,避免触发频率限制
      .create();
  }
}

2. 突破单次6分钟运行时限制的方法

Apps Script的单次运行6分钟限制是官方硬性配额,无法直接突破,但可以通过分段执行+触发器的方式绕开:

  • 记录进度:将每次处理到的goods_id索引存储在脚本属性(PropertiesService)或电子表格的某个单元格中,确保每次运行都能从上次中断的位置继续。
  • 时间驱动触发器:设置时间驱动触发器(比如每10分钟运行一次),每次运行处理一小批量数据(如500条),确保单次运行时长控制在6分钟以内。
  • 按需触发:在每次运行结束时,如果未完成全部任务,自动创建一个一次性触发器,让脚本在短时间后继续执行(如示例代码中所示)。

3. 每日1小时运行时限制的突破可能性

免费版Apps Script的每日1小时运行时限制是官方配额,无法突破。如果需要更高的配额,可以考虑:

  • 升级到Google Workspace付费版:付费版用户的每日运行时配额更高(如基础版为3小时,企业版更高),可满足更长时间的脚本运行需求。
  • 拆分任务到多个账号:如果有多个Google账号,可以将任务拆分到不同账号的脚本中运行,但这种方式需要额外的管理成本,且需遵守Google的服务条款。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 19:50:17