AI爬虫(GPTBot/ClaudeBot等)基本不执行JavaScript,用curl模拟抓取结果可判断内容是否对AI可见,客户端渲染页面有SEO盲区。
现在就对你的网站运行一下:
curl -s https://yoursite.com | grep -o "<h1[^>]*>.*</h1>"
如果没有返回结果,或者得到一个空的 <div id="root">,那么互联网的很大一部分根本无法读取你的网站。不是"读取效果不好",是根本无法读取。
我会在每个接手的网站上做这个测试,而结果往往出乎人们意料,所以值得写下来。
curl 只做一件事:获取 HTML 然后停止。它不运行 JavaScript,不等待 hydration,不调用你的 API。
这也是大量爬虫的做法。
Googlebot 是人们想到的例外,而且它确实做得很好:获取 HTML、把页面加入队列、之后用无头浏览器渲染。客户端渲染的内容最终通常会被收录。
AI 爬虫则是另一回事。截至目前,主要的 AI 爬虫(GPTBot、ClaudeBot、PerplexityBot 等)基本上不执行 JavaScript。它们获取 HTML、取出其中的内容、然后离开。你的框架在 bundle 加载后渲染的任何东西,对它们来说都是不可见的。
所以 curl 是一个不错的代理基准:如果你的内容不在那个响应里,可以认为相当一部分自动化读取者永远看不到它。
多年来,这个赌注是合理的。Google 会渲染 JS,Google 就是搜索,所以客户端渲染是可以接受的。
然后很大一部分发现渠道转移到了助手。人们向 ChatGPT 寻求推荐,而不是滚动十条蓝色链接。如果模型无法读取你的页面,你就不会出现在答案里,而搜索结果没有第二页可翻。
对于一个营销网站来说,这就是全部。对于小型企业来说更糟,因为那些重要的查询("X 地的网页设计师"、"附近谁做 Y")恰恰是人们现在向助手提出的问题。
curl -s https://yoursite.com | wc -c # 总字节数
curl -s https://yoursite.com | \
sed 's/<script[^>]*>.*<\/script>//g' | \
sed 's/<[^>]*>/ /g' | wc -w # 实际可见词数
一个营销主页在原始 HTML 中只有 40 个真实单词,这是一个红旗。React SPA 通常返回不到 10 个词。
// 在你的实际网站上打开 DevTools 控制台
document.body.innerText.split(/\s+/).length
把这个数字与上面的 wc -w 对比。差距有多大,就意味着你的网站有多少内容只有在 JavaScript 运行后才存在。
curl -s -A "GPTBot" https://yoursite.com | grep -c "your-key-phrase"
也值得确认你没有意外屏蔽了这些爬虫。很多 robots.txt 文件悄悄地禁止了它们,因为有人在 2023 年从博客文章里复制了一个屏蔽列表:
User-agent: GPTBot
Disallow: /
这是一个你可以主动做出的选择。意外为之代价高昂。
Next.js App Router。服务端组件是默认的,所以大多数情况下你没问题,直到有人在页面顶部加了 "use client" 来使用一个 hook。把 "use client" 下沉到需要它的叶子组件,而不是放在页面层级。
// page.tsx 保持服务端组件
export default async function Page() {
const data = await getData();
return (
<>
<h1>{data.title}</h1>
<p>{data.summary}</p>
<InteractiveWidget /> {/* 只有这个是 "use client" */}
</>
);
}
现在标题和文案都在 HTML 里了。组件在之后 hydration。双方读者都被服务到了。
Vite、CRA、纯 SPA。你需要预渲染。vite-plugin-ssr / Vike,或者为已知路由添加预渲染步骤,或者把营销页面移到静态 HTML,把 SPA 保留给应用本身。这种分离通常是诚实的答案:你的仪表盘不需要可爬取,但你的定价页面需要。
Astro / Eleventy / Hugo。已经是静态的了。但还是要检查,因为一个客户端 island 仍然可能在有人热情过头时吞掉你的主要内容。
任何在 Cookie 横幅后面导致页面空白的内容。一些同意实现会渲染一个插页式弹窗,在点击之前什么都不显示。爬虫不会点击。
助手会引用文字。给它们值得引用的文字。
一个 <h1> 用客户会用的词而不是 slogan 来陈述你是做什么的。
回答页面上的实际问题。如果人们问"多少钱",一个写着"根据需求定制价格"的页面无法给模型任何可重复的内容。
把事实放在正文里,而不只是放在图片或图标网格里。Alt 文字不是句子的替代品。
把重要内容放在视口上方,且在 DOM 顺序上,而非仅在视觉上。
去年我们重建了一个制造商的网站,整个产品线都在一个 JavaScript 轮播里。原始 HTML 只包含公司名称和一个 Cookie 提示。把产品文案移到服务端渲染的标记中是大部分工作,这不是重新设计,是一个穿着框架外衣的文本问题。
# 1. 是否有内容?
curl -s https://yoursite.com | sed 's/<[^>]*>/ /g' | wc -w
# 2. h1 是否存在?
curl -s https://yoursite.com | grep -o "<h1[^>]*>[^<]*"
# 3. 你在屏蔽爬虫吗?
curl -s https://yoursite.com/robots.txt
# 4. 关键短语是否还在?
curl -s https://yoursite.com | grep -c "what you actually sell"
四条命令。如果四条都有问题,这不是安排到下个季度解决的 SEO 问题。是网站不可读,而通常这个修复比重新设计要小得多。
在把它用到客户网站之前,先在自己的网站上运行。我不止一次被结果惊到。