求助:编写Google Sheet AppScript批量获取URL的标题、描述等元数据
解决Google Sheet批量提取URL元标签的问题
问题根源
IMPORTXML成功率低是因为不同网站的元标签结构没有统一标准:
- Title可能在
<title>标签,也可能在og:title元标签 - Description可能是
name="description"或property="og:description" - Logo的位置更分散:
og:image、rel="apple-touch-icon"、rel="icon"都有可能
单一XPath根本覆盖不了所有情况,得用更灵活的脚本处理。
用Google Apps Script实现批量提取
下面的脚本会自动处理多种标签结构,把结果写入相邻列,新手也能直接用:
function extractMetaTags() { const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); const urlColumn = 1; // URL在A列(从1开始计数) const startRow = 2; // 第1行是表头,从第2行开始处理 const lastRow = sheet.getLastRow(); // 批量获取所有URL const urls = sheet.getRange(startRow, urlColumn, lastRow - startRow + 1).getValues(); // 遍历每个URL,提取信息 urls.forEach((row, index) => { const url = row[0]; if (!url) return; // 跳过空行 let title = ""; let description = ""; let keywords = ""; let logo = ""; try { // 发送请求获取HTML,设置模拟浏览器的User-Agent避免被拦截 const options = { 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' } }; const response = UrlFetchApp.fetch(url, options); const html = response.getContentText(); const doc = XmlService.parse(html); const root = doc.getRootElement(); // 提取Title:先取<title>标签,再取og:title const titleElements = root.getDescendants().filter(elem => elem.getName() === 'title'); if (titleElements.length > 0) { title = titleElements[0].getText().trim(); } else { const ogTitle = root.getDescendants().filter(elem => elem.getAttribute('property')?.getValue() === 'og:title' ); if (ogTitle.length > 0) title = ogTitle[0].getAttribute('content')?.getValue().trim() || ""; } // 提取Description:先取name="description",再取og:description const descMeta = root.getDescendants().filter(elem => elem.getAttribute('name')?.getValue() === 'description' ); if (descMeta.length > 0) { description = descMeta[0].getAttribute('content')?.getValue().trim() || ""; } else { const ogDesc = root.getDescendants().filter(elem => elem.getAttribute('property')?.getValue() === 'og:description' ); if (ogDesc.length > 0) description = ogDesc[0].getAttribute('content')?.getValue().trim() || ""; } // 提取Keywords:name="keywords" const keywordsMeta = root.getDescendants().filter(elem => elem.getAttribute('name')?.getValue() === 'keywords' ); if (keywordsMeta.length > 0) { keywords = keywordsMeta[0].getAttribute('content')?.getValue().trim() || ""; } // 提取Logo:优先级og:image > apple-touch-icon > favicon const ogImage = root.getDescendants().filter(elem => elem.getAttribute('property')?.getValue() === 'og:image' ); if (ogImage.length > 0) { logo = ogImage[0].getAttribute('content')?.getValue().trim() || ""; } else { const appleIcon = root.getDescendants().filter(elem => elem.getAttribute('rel')?.getValue() === 'apple-touch-icon' ); if (appleIcon.length > 0) { logo = appleIcon[0].getAttribute('href')?.getValue().trim() || ""; } else { const favicon = root.getDescendants().filter(elem => elem.getAttribute('rel')?.getValue() === 'icon' ); if (favicon.length > 0) logo = favicon[0].getAttribute('href')?.getValue().trim() || ""; } } // 处理相对路径的Logo URL if (logo && !logo.startsWith('http')) { const urlObj = new URL(url); logo = `${urlObj.protocol}//${urlObj.host}${logo.startsWith('/') ? '' : '/'}${logo}`; } } catch (e) { // 处理请求失败的情况,比如网站无法访问 title = "请求失败"; description = e.toString(); } // 把结果写入相邻列:B=Title, C=Description, D=Keywords, E=Logo const resultRow = startRow + index; sheet.getRange(resultRow, 2).setValue(title); sheet.getRange(resultRow, 3).setValue(description); sheet.getRange(resultRow, 4).setValue(keywords); sheet.getRange(resultRow, 5).setValue(logo); // 每处理10个URL暂停1秒,避免触发请求限制 if ((index + 1) % 10 === 0) { Utilities.sleep(1000); } }); SpreadsheetApp.getUi().alert("提取完成!"); }
使用步骤
- 打开你的Google Sheet,点击顶部菜单栏的「扩展」→「Apps Script」
- 删除默认的
myFunction,粘贴上面的代码 - 根据你的表格修改参数:
- 如果URL在B列,把
urlColumn改成2 - 如果第1行不是表头,把
startRow改成1
- 如果URL在B列,把
- 点击工具栏的运行按钮,第一次运行会要求授权,按照提示完成授权(Google会提示脚本未验证,点击「高级」→「继续访问」即可)
- 等待脚本运行完成,结果会自动写入B-E列
注意事项
- Google Apps Script有每日请求配额,几百个URL建议分2-3次运行,或者调整脚本里的暂停时间
- 部分动态渲染的网站(比如用React/Vue构建的单页应用),静态解析HTML拿不到元标签,这种情况需要用Puppeteer,但配置起来更复杂,新手可以先处理静态网站
- 如果遇到某个网站一直请求失败,可能是对方有反爬机制,可以尝试修改
User-Agent的值
内容的提问来源于stack exchange,提问作者AyS 0908
相关产品推荐
相关产品推荐

