使用Google Apps Script获取网页截图多次后触发服务器错误求解决
解决Google Apps Script截图脚本多次运行后出现服务器错误的问题
错误原因
你当前使用的脚本依赖Charts服务渲染HTML并生成图片,这属于非官方的“取巧”用法——Google并未将Charts服务设计为网页截图工具,因此多次调用后容易触发服务器侧的资源限制或渲染异常,导致出现We're sorry, a server error occurred的错误。
解决方案
方案1:使用Google Cloud Functions + Puppeteer(稳定可靠)
这是专业且长期可用的网页截图方案,步骤如下:
- 新建Google Cloud Function,选择Node.js环境
- 在
package.json中添加依赖:
{ "dependencies": { "puppeteer": "^21.0.0" } }
- 编写截图函数代码:
const puppeteer = require('puppeteer'); exports.takeScreenshot = async (req, res) => { // 启动无头Chrome const browser = await puppeteer.launch({ args: ['--no-sandbox', '--disable-setuid-sandbox'] }); const page = await browser.newPage(); // 设置视口并加载目标页面 await page.setViewport({width: 1000, height: 2000}); await page.goto('https://pagespeed.web.dev/report?url=http://www.cool.haus', { waitUntil: 'networkidle2' // 等待页面加载完成 }); // 生成截图 const screenshotBuffer = await page.screenshot({fullPage: true}); await browser.close(); // 返回截图或上传到Drive(可根据需求调整) res.set('Content-Type', 'image/png'); res.send(screenshotBuffer); };
- 部署Cloud Function后,在Google Apps Script中通过
UrlFetchApp调用该函数的URL,获取截图并保存到Drive:
function callScreenshotFunction() { const functionUrl = '你的Cloud Function部署URL'; const response = UrlFetchApp.fetch(functionUrl); const blob = response.getBlob().setName('pagespeed_report.png'); DriveApp.createFile(blob); }
方案2:添加重试机制(临时缓解)
如果暂时不想搭建Cloud Function,可以给原脚本添加指数退避重试逻辑,降低临时服务器错误的影响:
function getScreenShot() { const url = "https://pagespeed.web.dev/report?url=http://www.cool.haus"; const maxRetries = 3; let retryCount = 0; while (retryCount < maxRetries) { try { const blob = Charts .newTableChart() .setDataTable(Charts.newDataTable().addColumn(Charts.ColumnType.STRING, "").addRow([`<meta http-equiv="refresh" content="0; URL='${url}'">`]).build()) .setOption('allowHtml', true) .setDimensions(1000, 2000) .build() .getBlob(); DriveApp.createFile(blob.setName("sample.png")); console.log("截图成功"); return; } catch (e) { retryCount++; console.log(`重试第${retryCount}次,错误信息:${e.message}`); // 指数退避等待,避免频繁请求触发限制 Utilities.sleep(Math.pow(2, retryCount) * 1000); } } throw new Error("经过3次重试后仍无法完成截图"); }
注意:该方案仅为临时缓解,无法从根本解决Charts服务的局限性,长期使用仍推荐方案1。
方案3:使用第三方截图API(快速实现)
若不想搭建服务,可选择支持JavaScript渲染的第三方截图API,示例代码:
function getScreenShotWithAPI() { const apiKey = '你的API密钥'; const targetUrl = encodeURIComponent('https://pagespeed.web.dev/report?url=http://www.cool.haus'); const apiUrl = `https://api.screenshotlayer.com/api/capture?access_key=${apiKey}&url=${targetUrl}&viewport=1000x2000&fullpage=1`; const response = UrlFetchApp.fetch(apiUrl); const blob = response.getBlob().setName('sample.png'); DriveApp.createFile(blob); }
注:需注册对应API获取密钥,注意免费额度及调用限制。
内容的提问来源于stack exchange,提问作者user12736831
相关产品推荐
相关产品推荐

