搜索抓取

服务端 HTML 与渲染后 DOM:搜索蜘蛛在哪一层看到 URL

很多站点把详情链接交给前端脚本生成,URL 只存在于渲染后的 DOM 里,发现渠道随之收窄。本文拆开抓取链路上的原始响应与渲染两个阶段,说明哪些写法会让链接延后出现,给出禁用 JS 对比、源码检索等自查步骤,以及把关键入口放回服务端 HTML 的几种做法。

搜索抓取

服务端 HTML 与渲染后 DOM:搜索蜘蛛在哪一层看到 URL

抓取一个 URL 时,搜索蜘蛛通常先拿到服务端直接返回的响应:状态码、响应头和 HTML 源码。渲染(执行 JS 得到 DOM)是之后的事,是否发生、何时发生并不完全由站点决定。理解这两级差异,能解释不少“页面明明有链接,却没被发现”的情况。

抓取链路上的两个阶段

第一阶段是原始响应。Sitemap 里的地址、HTML 里的 a href、日志中能看到的那次请求,大多在这一层完成。第二阶段是渲染:脚本执行、接口返回、节点插入,最后得到用户看到的 DOM。渲染资源是有限的,站点规模越大,落到单个 URL 上的渲染次数越少。

两个阶段对 URL 发现的意义并不相同:第一阶段决定“这个地址能不能被发现”,第二阶段更多决定“内容能不能被完整理解”。把关键入口只放在第二阶段,等于把发现权交给一个并不确定的环节。

哪些写法会让 URL 只出现在渲染后

  • 前端路由:列表和详情地址由 JS 生成,源码里只有空容器。
  • 懒加载与无限滚动:滚动或点击后才请求下一批数据,地址藏在接口响应里。
  • 接口拼装:模板由 fetch 回来的 JSON 渲染,链接文本和 href 都来自数据。
  • 按钮跳转:点击后执行脚本跳转,源码里没有可跟随的链接。

这些做法本身不会必然导致不抓取。真实情况是发现渠道从“内链”收窄到“Sitemap 与接口地址”,一旦 Sitemap 没覆盖到,这批 URL 就只能等外部链接或推送带进来,节奏明显变慢。

自查:确认 URL 在哪一层可见

  1. 用 curl 或查看网页源代码,直接搜索目标详情 URL 是否出现在原始 HTML 中。
  2. 以禁用 JS 的方式抓取同一列表页,统计可发现的链接数量,与浏览器中看到的作对比。
  3. 对比“查看网页源代码”和开发者工具 Elements 面板里的链接数,差值就是渲染层新增的部分。
  4. 在日志里观察渲染请求与普通抓取请求的分布,看哪些栏目几乎只有渲染访问。
  5. 抽一个详情页,确认它的入口究竟是 Sitemap、内链,还是只存在于某个接口响应中。

做完这几步,通常能得到一张清晰的图:哪些栏目的入口是稳的,哪些完全依赖渲染或推送。

把关键入口放回原始 HTML

  • 列表页尽量服务端渲染,至少保证首屏的详情链接以真实 a href 出现在源码里。
  • 分页、翻页、下一页使用可跟随的链接,而不是纯 JS 事件。
  • 懒加载保留前若干条为静态链接,其余再交给脚本补充。
  • 客户端路由的站点,对重点栏目做预渲染或静态化输出。
  • 无论采用哪种方案,Sitemap 都要覆盖全部详情地址,作为发现渠道的兜底。
渲染抓取是补充手段,不是内链的替代品。能放在原始 HTML 里的入口,尽量不要只留在脚本执行之后。

核对时容易忽略的点

一是缓存差异:CDN 或页面缓存返回的 HTML 可能与渲染服务看到的版本不同,核对时要确认请求命中的是哪一份。二是接口权限:抓取侧没有登录态,接口返回空数组,渲染出来的 DOM 自然也没有链接。三是移动与桌面模板不同,入口数量可能不一致,需要分别检查。四是改了前端框架后,旧的内链可能整体消失,而日志里的抓取趋势变化往往滞后几周才明显。

把这些点按栏目记录一次,后续每次改版前后对比链接数量,URL 发现的稳定性会比依赖人工抽查靠谱得多。