你的SPA网站,百度可能根本看不见

你花两周搭了个炫酷的单页应用,路由跳转丝滑、动画一气呵成,连产品经理都夸“这体验比XX App还顺”。但上线一个月后,你搜自己公司名,首页都排不进前三——不是没做SEO,是百度压根没把你当“有内容的网站”看。

它看到的,很可能就一个空荡荡的 <div id="app">


为什么爬虫在SPA里就像“瞎子”?

传统网页打开就是HTML:标题、正文、链接,清清楚楚。爬虫扫一眼就走,效率高得像快递员扔完包裹转身就跑。

SPA不是这样。它先扔给你一个几乎啥都没有的HTML壳子,再靠JavaScript一点点把内容“画”出来——加载JS、请求API、拼DOM、触发渲染……整个过程,用户等3秒觉得正常,爬虫等1秒就关页面。

我帮一个做在线题库的团队查过日志:他们首页JS执行要2.7秒,而百度爬虫平均只停留0.8秒。结果呢?上线半年,百度只收录了首页和4个内页,点开全是“数据加载中…”。

百度确实说能执行JS,但实际很保守:超时就放弃、遇到复杂异步就跳过、懒加载图片和文字?基本当不存在。不是它不想看,是你没给它“读得懂”的机会。


3种最常见的“伪收录”陷阱,你踩过几个?

很多人以为“百度搜得到”,就等于被收录了。其实只是幻觉。

第一种:收录了,但点进去是白屏。
你在百度搜 site:yourdomain.com,看到几十个URL。点开一个,页面空白,F12一看,DOM里只有 <div id="app"></div> 和一堆 <script>。这种收录毫无价值——用户进来就走,跳出率直接拉满。

第二种:首页能见,内页全失踪。
首页勉强能抓到,因为路径简单、JS少;但产品页、详情页、用户中心这些,全靠前端路由跳转。爬虫不会点按钮、不会触发 history.pushState,它连“下一页”在哪都不知道。

第三种:收录了,但内容张冠李戴。
有个客户的产品页被收录了,但标题显示的是“关于我们”,描述是一串乱码。查下来发现:路由切换后,<title> 标签根本没更新,爬虫只抓了初始状态。这种错乱比不收录更伤——用户会觉得你网站不可信。

说白了,问题不在爬虫笨,而在我们总把它当“人”用,忘了它本质是个只认静态HTML的文本阅读器。


服务端渲染SSR:最笨但最有效的方法

想让百度真正看懂你的SPA?SSR(服务端渲染)不是最优解,是目前唯一被验证有效的解。

做法很直白:用户或爬虫一请求,服务器先把页面内容渲染成完整HTML,再发出去。爬虫拿到的就是带标题、带正文、带结构的真·网页;浏览器收到后,再“激活”交互逻辑(这个过程叫水合)。

我们帮一家教培机构把Vue SPA迁到Nuxt.js(Vue生态的SSR框架),原来百度收录不到20个页面,两个月后稳定在200+,不少课程长尾词开始出现在搜索结果前两页。

当然,SSR要多扛一部分服务器压力——以前静态资源甩给CDN就行,现在每次访问都要服务端计算。但如果你的流量还没到单日万级,这点开销远不如“没人搜得到”来得痛。

如果项目小、内容更新不频繁,也可以试试预渲染:构建时就把所有路由对应的HTML提前生成好,部署成静态文件。比如用 prerender-spa-plugin,适合官网、介绍页这类场景。

别指望“等百度升级算法”,它现在就能读懂SSR输出的HTML。


动态渲染:给爬虫开“VIP通道”

SSR成本高、周期长?那动态渲染是第二选择:检测来访者是不是爬虫,是——就返回预渲染好的HTML;不是——照常走SPA流程。

相当于在门口装了个识别器:穿工装的是工人,走正门;穿西装的是访客,走VIP通道。

落地方式有两种:

  • 自己搭中间件:在Nginx或Node层判断User-Agent,匹配到 Baiduspider 就转发给Puppeteer或Rendertron服务,让它实时渲染并返回HTML。
  • 用云平台现成能力:阿里云Web应用防火墙、百度云SEO加速,都支持配置动态渲染规则,填个域名、选个模式,几分钟搞定。

真实案例:一家金融资讯站,内容天天更新,但百度收录慢得像蜗牛。上了动态渲染后,新发布的文章平均3天内就被收录,之前要等一两周甚至更久。

注意一个雷区:爬虫看到的HTML,必须和用户最终看到的一模一样。少渲染一段文案、漏掉一个<meta>,百度会判定为“隐藏内容”,轻则降权,重则拒收。


别忘了这些“小细节”,它们能救你的命

大方案再好,细节塌方,照样白干。

第一,路由切换时,必须同步更新 <title><meta name="description">
很多SPA只在入口文件写死一个标题,后面所有页面都是“首页 - XXX公司”。百度抓取时就按这个存档,结果上千个页面标题重复,直接被当成垃圾站处理。

第二,别用 #/about 这种hash路由。
# 后面的内容,百度基本不解析。它只认 /about/article/123 这种标准路径。用Vue Router或React Router时,记得开 history 模式,而不是默认的 hash 模式。

第三,sitemap不能交一次就吃老本。
哪怕你是SPA,也得有sitemap。而且得是“活”的:新上一篇博客、新增一个产品页,就得自动加进sitemap.xml,并重新提交到百度站长平台。很多团队上线时提了一次,之后三年没动过。

第四,去百度搜索资源平台翻抓取日志。
不是看“收录量”,是看“哪些URL返回了404/500/超时”。日志里藏着最真实的线索:某个详情页接口挂了,爬虫反复失败;某个路由配置错了,返回空白HTML……80%的人从不点开这页,但问题就藏在这里。


今天就能做的1个操作:用“curl”测试你的页面

别收藏,别“稍后看”,现在就打开终端(Mac/Linux)或 Windows PowerShell,粘贴运行这一行:

curl -H "User-Agent: Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)" https://yourdomain.com/product/abc

https://yourdomain.com/product/abc 换成你最想被收录的那个页面地址。

看返回结果:

  • 如果里面有真实的标题、正文段落、产品参数——说明爬虫至少能读到内容;
  • 如果只有 <div id="app"><script src="...">、或者“加载中…”——你的SPA对百度来说,就是一张白纸。

如果是后者,今天就打开你的项目,挑一个最核心的页面(比如首页或产品列表页),在构建流程里加上 prerender-spa-plugin,或者在路由守卫里补上 <title> 动态更新逻辑。做完这一步,你已经比多数同行快了一步。