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
相关产品推荐
相关产品推荐

