Google Apps Script批量调用API获取MMORPG物品价格求助
批量获取MMORPG物品定价数据解决方案
以下是修改后的代码,可实现批量处理D8:D24区域的itemID,并将对应最低价格写入F列对应行:
function getPrices() { const baseUrl = "https://universalis.app/api/v2/world/"; const sheet = SpreadsheetApp.getActiveSheet(); if (sheet.getName() !== 'Boss Weapons') return; // 获取D8:D24的itemID列表,过滤空值 const idRange = sheet.getRange('D8:D24'); const itemIDs = idRange.getValues() .flat() // 将二维数组转为一维数组 .filter(id => id.toString().trim() !== ''); // 移除空单元格的无效ID // 构建所有请求的完整URL const requestUrls = itemIDs.map(id => `${baseUrl}${id}?listings=0&entries=0`); try { // 批量发起API请求(Google Apps Script原生批量方法,效率更高) const responses = UrlFetchApp.fetchAll(requestUrls); // 解析每个响应的minPrice,加入错误容错 const prices = responses.map((response) => { try { const data = JSON.parse(response.getContentText()); return [data.minPrice || '无数据']; // 无定价时返回提示文本 } catch (e) { return ['API请求失败']; // 单个请求出错时返回提示 } }); // 批量写入结果到F8:F24 const targetRange = sheet.getRange('F8:F24'); targetRange.setValues(prices); } catch (e) { SpreadsheetApp.getUi().alert(`批量请求出错: ${e.message}`); } }
关键修改说明
- 批量ID读取:通过
getRange('D8:D24').getValues()获取整个目标区域的ID,用flat()简化数组结构,filter()过滤空值避免无效请求。 - 批量API请求:使用
UrlFetchApp.fetchAll()替代单个fetch(),这是Google Apps Script专门优化的批量请求方法,比手动用Promise.all()更适配平台环境。 - 结果批量写入:用
setValues()一次性写入所有结果,比逐个setValue()的执行效率提升数倍。 - 错误容错:加入多层try-catch,避免单个请求失败导致整个脚本崩溃,同时给用户明确的错误提示。
关于Promise.all的适配方案
如果一定要用Promise.all()实现,需要先将同步的UrlFetchApp.fetch()封装为Promise,再结合async/await使用:
// 封装同步请求为Promise function fetchAsPromise(url) { return new Promise((resolve, reject) => { try { const response = UrlFetchApp.fetch(url); resolve(response); } catch (e) { reject(e); } }); } // 使用Promise.all的版本 async function getPricesWithPromise() { const baseUrl = "https://universalis.app/api/v2/world/"; const sheet = SpreadsheetApp.getActiveSheet(); if (sheet.getName() !== 'Boss Weapons') return; const idRange = sheet.getRange('D8:D24'); const itemIDs = idRange.getValues() .flat() .filter(id => id.toString().trim() !== ''); const requestUrls = itemIDs.map(id => `${baseUrl}${id}?listings=0&entries=0`); try { // 用Promise.all批量处理异步请求 const responses = await Promise.all(requestUrls.map(url => fetchAsPromise(url))); const prices = responses.map((response) => { try { const data = JSON.parse(response.getContentText()); return [data.minPrice || '无数据']; } catch (e) { return ['API请求失败']; } }); sheet.getRange('F8:F24').setValues(prices); } catch (e) { SpreadsheetApp.getUi().alert(`批量请求出错: ${e.message}`); } }
注意:使用async/await和Promise.all()时,需确保脚本运行在V8引擎环境下(Google Apps Script默认已启用)。
内容的提问来源于stack exchange,提问作者Decimus
相关产品推荐
相关产品推荐

