如何在Google Apps Script中批量检测站点GTM标签安装状态
批量检测客户站点GTM容器标签的问题
问题背景
- 需持续检查一批客户站点是否安装我方GTM容器标签
- 公司统一登录账号与表格关联的谷歌账号不一致,无法将表格绑定到GTM,也无法在容器中添加个人标签
- 单站点检测代码可正常运行,但批量检测失效,希望实现无需手动触发的循环检测,尝试用
array.map但不会操作 - 使用
fetchAll做批量检测时触发错误:Exception: Service invoked too many times in a short time: urlfetch. Try Utilities.sleep(1000) between calls.,添加Utilities.sleep后问题仍未解决
现有可用单站点检测代码
function verifyGTM() { var ss = SpreadsheetApp.getActiveSpreadsheet(); var s = ss.getSheetByName('February 2023 Paste'); var urlRange = s.getRange(5,10); var gtmRange = s.getRange(5,11); var url = urlRange.getDisplayValues(); var gtmID = gtmRange.getDisplayValues(); var str = UrlFetchApp.fetch(url).getContentText(); const mainRegex = /<!-- Google Tag Manager -->([\s\S]*?)<!-- End Google Tag Manager -->/gi; var results = str.match(mainRegex); Logger.log(results) if(str.includes("GTM") && str.includes(gtmID) && !gtmID == "N/A"){ s.getRange(5,12).setValue("Yes"); } else if(str.includes("GTM") && !str.includes(gtmID)){ s.getRange(5,12).setValue("Incorrect GTM"); } else if(gtmID == "N/A"){ s.getRange(5,12).setValue("No GTM"); } else { s.getRange(5,12).setValue("No"); } }
批量检测尝试代码(未生效)
function verifyGTM() { var ss = SpreadsheetApp.getActiveSpreadsheet(); var s = ss.getSheetByName('February 2023 Paste'); var urlRange = s.getRange("J:J"); var gtmRange = s.getRange("K:K"); var url = urlRange.getDisplayValues(); var gtmID = gtmRange.getDisplayValues(); var str = UrlFetchApp.fetchAll(url).getContentText(); const mainRegex = /<!-- Google Tag Manager -->([\s\S]*?)<!-- End Google Tag Manager -->/gi; var results = str.match(mainRegex); Logger.log(results) if(str.includes("GTM") && str.includes(gtmID) && !gtmID == "N/A"){ s.getRange("L:L").setValue("Yes"); } else if(str.includes("GTM") && !str.includes(gtmID)){ s.getRange("L:L").setValue("Incorrect GTM"); } else if(gtmID == "N/A"){ s.getRange("L:L").setValue("No GTM"); } else { s.getRange("L:L").setValue("No"); } }
解决方案
核心修改点
- 避免全列读取:读取整列会包含大量空行导致无效请求,改为读取有数据的行范围
- 处理
fetchAll返回格式:fetchAll返回响应对象数组,需逐个解析内容 - 分批次加延迟:拆分请求批次,每批次后添加延迟,规避频率限制
- 批量写入结果:一次性写入所有检测结果,减少Spreadsheet API调用次数
- 自动触发设置:通过时间触发器实现循环检测,无需手动操作
最终可用批量检测代码
function batchVerifyGTM() { const ss = SpreadsheetApp.getActiveSpreadsheet(); const sheet = ss.getSheetByName('February 2023 Paste'); // 获取有数据的最后一行,从第5行开始检测 const lastRow = sheet.getLastRow(); if (lastRow < 5) return; // 读取J-K列的有效数据(第5行到最后一行) const dataRange = sheet.getRange(5, 10, lastRow - 4, 2); const data = dataRange.getDisplayValues(); const requests = []; const gtmIds = []; // 整理请求列表和对应GTM ID,过滤空URL data.forEach(row => { const url = row[0].trim(); const gtmId = row[1].trim(); if (url) { requests.push({url: url, muteHttpExceptions: true}); // 忽略HTTP错误,避免流程中断 gtmIds.push(gtmId); } else { gtmIds.push(null); } }); const batchSize = 10; // 每批次请求数量,可根据限制调整 const results = []; // 分批次处理请求,添加间隔延迟 for (let i = 0; i < requests.length; i += batchSize) { const batch = requests.slice(i, i + batchSize); const responses = UrlFetchApp.fetchAll(batch); responses.forEach((res, index) => { const gtmId = gtmIds[i + index]; if (!gtmId) { results.push([""]); return; } const content = res.getContentText(); let status; if (gtmId === "N/A") { status = "No GTM"; } else if (content.includes("GTM") && content.includes(gtmId)) { status = "Yes"; } else if (content.includes("GTM")) { status = "Incorrect GTM"; } else { status = "No"; } results.push([status]); }); // 非最后一批次添加延迟 if (i + batchSize < requests.length) { Utilities.sleep(2000); // 延迟2秒,可根据实际情况调整 } } // 批量写入检测结果到L列 if (results.length > 0) { sheet.getRange(5, 12, results.length, 1).setValues(results); } } // 创建每日自动检测触发器(运行一次后自动创建,或手动在脚本编辑器触发器面板自定义频率) function createDailyTrigger() { ScriptApp.newTrigger('batchVerifyGTM') .timeBased() .everyDays(1) .create(); }
使用说明
- 将代码复制到谷歌表格的脚本编辑器中
- 先手动运行
batchVerifyGTM测试功能是否正常 - 若需要自动循环检测,运行
createDailyTrigger创建每日触发器,或在触发器面板自定义触发频率(如每小时、每周) - 可根据实际情况调整
batchSize和Utilities.sleep的时间值,平衡检测速度和频率限制
内容的提问来源于stack exchange,提问作者Michelle Schnitzmeier
相关产品推荐
相关产品推荐

