使用UrlFetchApp.fetchAll随机触发“Exception: ScriptError Exception: Address unavailable”错误的原因及解决方法咨询
我之前处理批量API请求时,也碰到过完全一样的随机报错问题!当时折腾了好一阵才找到靠谱的解决思路,分享给你:
错误到底是什么意思?
这个Address unavailable错误并不是说目标URL真的无法访问(毕竟你单独请求没问题),本质是Google的UrlFetch服务器在尝试和目标地址建立TCP连接时失败了。常见的触发原因有这几个:
- 批量并发请求时,目标服务器的防火墙/速率限制触发了临时拦截,直接拒绝了新的连接请求;
- Google的UrlFetch服务本身出现了短暂的网络波动,导致部分请求无法正常路由;
- 分组请求的密度太高,短时间内大量请求从同一个IP发出,被中间的CDN或路由节点判定为异常流量。
亲测有效的处理方案
1. 给分组请求加间隔延迟
不要一股脑连续发送所有分组,每组请求之间加个1-5秒的休眠时间,用Utilities.sleep(1000)(单位是毫秒)。我之前把分组间隔从0改成2秒后,错误率直接降到了原来的10%左右——降低请求密度是最有效的办法之一。
2. 缩小每组请求的规模
你现在是5-50个URL一组,可以试试把每组控制在10个以内。很多API服务器对单IP的并发连接数有限制,并发数越高,被拒绝连接的概率就越大。我后来把每组固定为8个,又减少了不少报错。
3. 给失败请求加重试机制
因为这个错误大多是临时的,所以把报错的URL收集起来,隔几秒后单独重试(或者组成更小的批次重试)。最多重试2-3次,基本能解决90%的随机报错问题。示例代码大概是这样:
function processUrlsInBatches(allUrls, batchSize = 8) { let allResults = []; let failedUrls = []; // 分批次处理 for (let i = 0; i < allUrls.length; i += batchSize) { let batch = allUrls.slice(i, i + batchSize); // 给每个请求加配置,开启异常静默方便后续处理 let requestConfigs = batch.map(url => ({ url: url, muteHttpExceptions: true, timeout: 10000, // 设置10秒超时 headers: {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'} })); let results = UrlFetchApp.fetchAll(requestConfigs); // 收集结果和失败的URL for (let j = 0; j < results.length; j++) { if (results[j] instanceof Error) { failedUrls.push(batch[j]); } else { allResults.push(results[j]); } } // 组间延迟 Utilities.sleep(2000); } // 重试失败的请求 if (failedUrls.length > 0) { console.log(`重试 ${failedUrls.length} 个失败请求`); Utilities.sleep(3000); let retryConfigs = failedUrls.map(url => ({ url: url, muteHttpExceptions: true, timeout: 10000, headers: {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'} })); let retryResults = UrlFetchApp.fetchAll(retryConfigs); // 合并最终结果(可以再处理仍然失败的) allResults = allResults.concat(retryResults.filter(res => !(res instanceof Error))); } return allResults; }
4. 完善请求配置
- 给请求加上合理的
User-Agent,模拟正常浏览器请求,有些服务器会拒绝没有UA的请求; - 设置合适的超时时间(比如10秒),避免因为目标服务器响应慢导致的连接超时被误判为地址不可用;
- 开启
muteHttpExceptions: true,这样不会直接抛出中断脚本的异常,方便你自己处理失败请求。
5. 排查临时服务异常
如果突然出现大量报错,可以检查下Google Apps Script的服务状态(比如是否有临时的故障通知),偶尔Google的UrlFetch服务会有短暂的路由问题,这种情况等一会儿就会恢复。
内容的提问来源于stack exchange,提问作者roma
相关产品推荐
相关产品推荐

