搭蜘蛛池的时候,入口页怎么生成是个绕不开的问题。有人图省事,直接套一个前端框架,页面内容全靠 JS 拉接口;也有人全部输出静态 HTML。两种做法蜘蛛都能遇到,但遇到的难度完全不一样。这篇文章只讨论一件事:入口页的内容,到底该在服务端就拼好,还是交给浏览器去渲染。
蜘蛛拿到 HTML 之后还要不要跑 JS
搜索引擎的抓取大致分两步:先抓 HTML,再决定要不要进渲染队列。渲染是有成本的,每个页面都要占计算资源,所以渲染队列通常比抓取队列慢得多,而且有配额。一个入口页如果关键内容、链接全在 JS 里,蜘蛛第一次拿到的其实是个空壳,只能排队等渲染。等得到算运气好,等不到就只留下一份内容稀薄的记录。
换句话说,静态输出是即时可见,JS 渲染是延迟可见。蜘蛛池入口页数量动辄几千上万,延迟一点点,整体效率就差很多。
静态 HTML 和前端渲染,差在哪几个地方
- 可见时间:静态内容抓取当次就能读到,JS 内容要等二次渲染。
- 链接发现:写了 a 标签的 URL 在 HTML 里就能被提取,靠 JS 拼接出来的链接往往要等渲染完才被发现,甚至永远发现不了。
- 失败率:渲染会受接口超时、跨域、第三方脚本加载失败影响,任何一环出问题,页面在蜘蛛眼里就是空的。
- 抓取预算消耗:渲染一个页面消耗的资源明显高于纯文本抓取,同样的预算能覆盖的页面数会变少。
三种常见方案怎么选
纯静态 HTML
入口页内容变化不频繁、主要目的是把链接和主题词递出去,静态就是最省事的方案。生成时把正文、标题、内链一次性写进 HTML,蜘蛛进来一次就能拿走全部信息,不需要排队渲染。
服务端渲染(SSR)
内容需要按参数变化、又不想放弃静态可见性时,可以在服务端把首屏拼好再返回。对蜘蛛来说,拿到的仍然是完整 HTML。代价是服务器压力更大,缓存没做好时 TTFB 容易变长,这一点要额外留意。
客户端渲染(CSR)加兜底
如果确实用了前端框架,至少要保证首屏关键内容直出,而不是依赖接口返回。剩下非关键部分再交给 JS,这样即使渲染失败,页面也不是一片空白。
坚持用 JS,也得守住几条线
- 入口页的主要链接必须写在 HTML 里,不要用 onclick 或 JS 跳转代替 a 标签。
- 标题、正文摘要这类核心内容尽量直出,不要等着接口返回再填。
- 少依赖第三方脚本、统计代码和外部字体,任何一个卡住都可能拖垮整页渲染。
- 不要用 JS 判断 UA 再决定给不给内容,容易误伤,也容易被当成作弊。
- 如果需要跳转,优先用标准 301 或 302,而不是 JS 里的 location.href。
几个常见的想当然
“搜索引擎都能渲染 JS,所以怎么写都行。”能渲染和一定渲染是两回事,渲染排期、配额、失败重试都要算进去。入口页数量一多,这个差别会被放大。
- 以为页面在浏览器里显示正常,蜘蛛看到的就是同一份内容,其实首屏可能靠接口,接口你有、蜘蛛不一定等得到。
- 以为把链接写在 JS 数组里也算内链,这更多是给用户看的,对 URL 发现帮助有限。
- 以为渲染过的页面会被永久记住,重新抓取时如果 HTML 还是空壳,判断可能回到原点。
一个简单的判断标准
判断方法很朴素:把页面 HTML 源码里的 JS 全部关掉,看还剩多少内容。如果标题、正文、内链都还在,说明方案是稳的;如果关掉 JS 只剩一个空 div,那就要考虑改造成静态输出或者 SSR。蜘蛛池要的是被快速、稳定地读到,而不是页面做得多花哨。