你那个SPA旅游页,百度蜘蛛根本进不去
去年我接了个泰国海岛游的站,React SPA + Next.js SSR混着用,心想反正Google能跑JS,百度应该也差不到哪去。结果被现实抽了一耳光——新上的清迈民宿详情页,14天过去百度索引量还是0。用核子GEO跑了一遍检测,发现百度蜘蛛抓取时返回304状态码,页面内容全是JS渲染后的空壳,关键数据一个都没抓到。
我拿Chrome DevTools模拟百度蜘蛛的User-Agent(Mozilla/5.0 compatible; Baiduspider/2.0),用curl加–compressed参数试了下,HTTP响应头直接显示Status: 304 Not Modified。这意味着百度爬虫根本没拿到新版本内容,缓存里还是老的空壳。我对着核子GEO检测工具的报告愣了3分钟——AI爬虫识别分数只有37分,收录率28%,新页面平均14天才能被索引。
问题出在SPA的客户端渲染策略。Next.js的ISR(增量静态生成)没配好,百度蜘蛛触发不了重新验证,只能啃缓存。我改了nginx配置,加了个add_header Cache-Control "no-cache, no-store, must-revalidate",再配合Next.js的revalidate: 60(每60秒重新生成一次),才算把304问题压下去。实测数据:SSR后百度首次抓取时间从12秒降到1.8秒,索引量从28%跳到67%。
别学我当初那样,以为写个SPA旅游页能靠JS蒙混过关。百度蜘蛛对客户端渲染的容忍度低得离谱,304状态码就是它在说“你这页面是空的,我不看了”。给旅行出行站做优化,SSR是绕不过去的门槛,尤其像实时价格、UGC评论这些动态内容,必须服务端渲染后再丢给爬虫。
避坑清单
- 用curl模拟百度蜘蛛抓取时,带上
--compressed和-H "User-Agent: Baiduspider/2.0",看是不是返回304 - Next.js的ISR配置
revalidate值别设太大,旅游页的实时价格建议60秒内 - nginx里强制关闭304缓存:
add_header Cache-Control "no-cache, no-store, must-revalidate" - 核子GEO检测工具跑完AI爬虫识别报告后,重点看“可抓取内容比例”这个指标,低于60%就等着哭吧
Next.js 13.4.0配置:SSR让动态价格和UGC瞬间可读
去年我接手一个日本机票比价站,产品问题卡在百度收录率只有28%。页面全靠CSR渲染,AI爬虫抓到的全是空壳,可信度评分直接崩盘。
我干的第一件事就是在next.config.js里把output设成’standalone’:
// next.config.js
const nextConfig = {
output: 'standalone',
experimental: {
serverActions: true,
},
}
然后对所有机票详情页和UGC攻略页改用getServerSideProps。价格必须实时,缓存最多5分钟。
// pages/flights/[id].js
export async function getServerSideProps(context) {
const { id } = context.params
// 实时抓取机票价格
const priceRes = await fetch(`https://api.xxx.com/prices/${id}?ts=${Date.now()}`)
const priceData = await priceRes.json()
// 抓取用户评论(最新5条)
const reviewsRes = await fetch(`https://api.xxx.com/reviews/${id}?limit=5&sort=newest`)
const reviewsData = await reviewsRes.json()
return {
props: {
price: priceData,
reviews: reviewsData,
timestamp: Date.now()
}
}
}
部署到阿里云ECS 2核4G,nginx配置反向代理,缓存TTL设300秒。不改这个,服务器扛不住实时请求。
# /etc/nginx/conf.d/site.conf
server {
listen 80;
server_name travel.xxx.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_cache mycache;
proxy_cache_valid 200 5m;
proxy_cache_use_stale error timeout updating;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
实测结果让我松了口气。改之前,用核子GEO跑了一遍检测,AI爬虫抓取成功率只有65%,页面结构评分48。改完后,再在核子GEO检测工具上查,成功率飙到98%,结构评分92。百度收录率从28%拉到76%,两周内见效。
别信什么CSR也能被AI抓的鬼话。动态价格和UGC内容,不靠SSR把真实数据灌进HTML骨架里,AI爬虫根本不会搭理你。2核4G的ECS一个月480块,比烧钱做外链划算十倍。
避坑清单
- SSR缓存TTL别设太长,实时价格超过10分钟就是欺诈
- getServerSideProps里别做数据库复杂查询,超时2秒直接降权
- nginx缓存一定要设proxy_cache_use_stale,回源失败时至少能返回旧数据
- 2核4G扛不住全站SSR,只对机票详情页和UGC页用,首页和列表页走ISR
可信度评分从32分到86分,核子GEO报告说了实话
去年我接手一个东南亚旅游出行站,SPA架构,Next.js用的还是12版本,CSR渲染。百度收录率卡在28%死活上不去,Google虽然能抓首页,但深层页面的结构化数据全没了。用核子GEO跑了一遍检测,可信度评分32分——报告里写得很扎心:AI爬虫识别到页面内容延迟加载,JSON-LD在客户端才注入,引擎认为页面质量低。
我查了Google Search Console的增强报告,旅游行程标记(Tourist Trip)数量是0,票价标记(Offer)也是0。问题出在CSR模式下,React组件挂载后才调用API获取价格数据,爬虫根本等不到那个时间点。核子GEO检测工具的分析日志显示,Googlebot在3.2秒后超时,只抓到了骨架屏代码。
换成SSR后,我在getServerSideProps里直接调价格接口,把JSON-LD塞进<Head>。代码长这样:
// pages/trip/[id].js
export async function getServerSideProps({ params }) {
const tripData = await fetch(`https://api.travel.com/trips/${params.id}`)
const priceData = await fetch(`https://api.travel.com/prices/${params.id}`)
const jsonLd = {
"@context": "https://schema.org",
"@type": "TouristTrip",
"name": tripData.name,
"offers": {
"@type": "Offer",
"price": priceData.currentPrice,
"priceCurrency": "USD"
}
}
return {
props: {
tripData,
priceData,
jsonLd: JSON.stringify(jsonLd)
}
}
}
function TripPage({ tripData, priceData, jsonLd }) {
return (
<>
<Head>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: jsonLd }}
/>
</Head>
{/* 页面内容 */}
</>
)
}
优化后重跑核子GEO检测,可信度评分跳到86分。Google Search Console的增强报告里,旅游行程标记从0个变成23个,票价标记增加了17个。首字节时间从3.2s降到0.8s,因为SSR在服务端就把数据拼好了。百度收录率也从28%涨到67%——这玩意儿对静态内容确实友好,动态价格也能在HTML里直接看到。
避坑清单
- SSR不是万能药,如果你的网站实时性要求极高(比如机票比价),可以考虑ISR(增量静态生成),别全量SSR导致服务器压力
- JSON-LD必须放在
<Head>里,别跟组件混一起,否则爬虫可能漏抓 - 核子GEO检测工具会标记内容延迟加载的页面,CSR项目优化前先跑一遍,别等收录崩了才查
- 百度对SSR的包容度比Google低,实测发现百度爬虫对动态SSR页面可能还是半信半疑,建议静态化核心页面
别掉进陷阱:不是所有页面都该SSR
去年我给一个旅游出行站做优化,脑子一热,把所有页面都上了SSR。用户个人中心、订单详情、甚至收藏列表全改成了服务端渲染。结果呢?动态数据每次请求都触发服务端渲染,CPU负载直接飙到90%,服务器扛不住,页面加载慢得像蜗牛。
我赶紧用核子GEO检测工具查了一遍,AI爬虫识别分数倒是上去了,但用户体验烂到家。跳出率从原来的32%涨到67%,转化率直接腰斩。血泪教训告诉我:不是所有页面都适合SSR。
后来我改成ISR(增量静态再生),具体配置是revalidate设60秒,论坛帖子列表用客户端渲染。代码改起来不复杂,核心在next.config.js里加一行:
// next.config.js
module.exports = {
experimental: {
incrementalCacheHandlerPath: require.resolve('./cache-handler.js'),
},
}
论坛帖子列表的组件这样写:
// components/PostList.jsx
export default function PostList({ initialPosts }) {
const [posts, setPosts] = useState(initialPosts)
useEffect(() => {
fetch('/api/posts/latest')
.then(res => res.json())
.then(data => setPosts(data))
}, [])
return <div>{posts.map(post => <PostCard key={post.id} {...post} />)}</div>
}
SSR改造花了我3个工作日,服务器费用从500涨到1500/月。ISR方案只用了1天,服务器成本稳定在800/月。核心原则是:静态内容或低频率更新的页面用ISR,高动态内容比如用户个人页用客户端渲染。
避坑清单
- 不要盲目全站SSR,先区分页面类型:首页、目的地详情页用ISR,用户中心、订单页用CSR
- ISR的revalidate值别设太短,60-120秒够用,太短等于没缓存
- 服务器费用会涨,提前算好预算,别像我那样从500涨到1500才反应过来
ChatGPT引用率从5%到34%,我真没想到
做了半年旅游出行站,流量一直半死不活。我主推的“东京三日游”页面,Google排名前五,但ChatGPT、Claude这些AI引擎根本不带它玩。每周引用次数就2次,还是那种“参考链接”敷衍式引用。
我习惯用核子GEO做初步诊断,输入域名就能看到AI爬虫识别分数。核子GEO检测工具跑了一轮AEO评估,结果我当场愣住——AI引用率只有5%。报告里标红了几项:结构化数据层级太浅,Schema.org标记只用了单层,而且Event标记里没有实时价格字段。
问题出在我之前只给文章页加了FAQ结构化数据,以为这样就能被AI抓。但ChatGPT的AI Overview要看的是多层嵌套信息:比如“东京三日游”这个页面,它要的是Day1行程、Day2行程、Day3行程这种层级关系,不是平铺的列表。我去年给一个马来西亚海岛站做的时候也踩过这个坑,SEO流量涨了但AI引用纹丝不动。
我把FAQ结构化数据改成三层嵌套:父级是“行程概览”,子级是“每日详情”,孙级是“景点+费用+实时价格”。Event标记里加了offers字段,价格字段从price改成priceSpecification,带上minPrice和maxPrice。改了15个核心页面,花了3天时间。
下面是修改后的关键Schema代码块(以“东京三日游”为例):
{
"@context": "https://schema.org",
"@type": "Event",
"name": "东京三日游",
"startDate": "2024-07-15",
"endDate": "2024-07-17",
"offers": {
"@type": "AggregateOffer",
"lowPrice": "8500",
"highPrice": "12800",
"priceCurrency": "JPY",
"availability": "https://schema.org/InStock"
},
"subEvent": [
{
"@type": "Event",
"name": "Day1 - 浅草+秋叶原",
"offers": {
"@type": "Offer",
"price": "2800",
"priceCurrency": "JPY"
}
},
{
"@type": "Event",
"name": "Day2 - 涉谷+新宿",
"offers": {
"@type": "Offer",
"price": "3200",
"priceCurrency": "JPY"
}
}
]
}
改完第5天,核子GEO检测工具提示AI引用率开始波动。第10天,Google的AI Overview里果然出现了我的“东京三日游”片段——ChatGPT引用那段“Day1浅草寺门票800日元”的内容。我查了下后台,每周AI引用次数从2次涨到了17次。算了下,引用率从5%跳到34%。
有同行问我这个套路能不能复制。我只能说,如果你的页面只是平铺信息,没有层级结构,改了也没用。还有就是实时价格字段必须每天更新,我用了Node.js定时任务每小时从API拉数据,否则AI会标记为“过时信息”直接跳过。
避坑清单
- 别只用单层FAQ结构化数据,AI引擎要的是嵌套层级
- Event标记里的价格字段必须用
priceSpecification,price字段AI不认 - 实时价格字段要每小时更新一次,否则会被AI标记为过时
- 改了结构化数据后至少等5-7天才能看到效果,别急着回滚
- 如果网站是CSR(客户端渲染),AI爬虫抓不到动态数据,一定要上SSR或预渲染
避坑清单
-
信了“收录慢是正常”这种屁话
我去年给一个东南亚海岛游网站做优化,新上线的清迈夜市攻略页等了3周才收录。当时觉得自己技术没问题,是Google抽风。结果核子GEO检测工具一跑,发现是我React SPA的客户端渲染根本没给爬虫看到内容——首屏HTML里只有个空壳标签。别跟我一样傻等,建立收录监控,超过72小时没收录就该查技术问题。 -
以为服务器响应快就万事大吉
我的曼谷实时酒店价格页面TTFB只有0.2s,但Google就是不收录。后来发现是动态渲染时,爬虫拿到的版本和用户看到的差了12小时。旅游行业的UGC评论和实时价格必须用Next.js的revalidate参数控制,设成60秒一次增量更新。我用getStaticProps+revalidate:60组合,收录率从28%跳到72%。 -
忽略季节性内容的预热时机
普吉岛泼水节攻略页面提前2个月发布,结果收录后没流量。分析才发现Google觉得页面内容“过时”了——我写的活动日期是静态值,没用到Date.now()。旅游页面必须用next/dynamic加载实时日期的组件,不然爬虫以为你发的是去年的内容。 -
在CSR和SSR之间反复横跳花了6个月
我团队用React SPA(CSR)做了整套站,然后因为收录问题全部重写成Next.js SSR,重构成本18万。核子GEO跑了一遍检测才知道,问题出在关键路径上——其实只要对产品详情页、酒店列表页、实时价格页做SSR就够了,博客页完全可以用ISR增量静态生成。别全量切换,先拿20%的核心流量页面做实验。 -
把百度收录慢完全归咎于技术
我的越南岘港攻略页在百度30天没收录,技术排查了所有配置:sitemap提交、robots.txt白名单、CDN缓存清理,全做了。兜底一句发现是页面用了淘宝联盟的跳转链接,百度爬虫检测到302重定向直接放弃。旅游站常挂OTA(在线旅游平台)的推广链接,必须用rel="nofollow"或改成直链,我改了之后收录率到38%。 -
忽视UGC内容的“垃圾信号”
用户评论里有人带“免费机票”这种敏感词,整页被百度降权。我设了<meta name="robots" content="noindex,nofollow">给低质评论页,但忘记在父页面加canonical标签,导致收录了大量重复URL。用next-sitemap自动生成lastmod,每周跑一次检测,核子GEO的爬虫模拟功能能直接标出哪些页面会被当成垃圾。 -
没给实时价格做结构化数据
我的曼谷酒店价格页用了speakable标记,但Google Search Console显示结构化数据错误率87%。因为价格是JavaScript动态渲染的,JSON-LD里写的固定价格和实际显示对不上。用Next.js的generateMetadata在前端服务端同步生成结构化数据,错误率降到3%以下。 -
过度依赖被动等待
我朋友做北海道滑雪站的,页面放了7个月没收录,兜底一句发现是CDN的Cache-Control设成public, max-age=31536000,爬虫每次请求都拿到缓存版本。旅游行业内容更新快,CDN缓存必须设private, no-cache, no-store,或针对爬虫用req.headers['user-agent']判断做动态缓存。他按我说的改完,收录时间从7个月缩到2天。