有些站点会遇到一种奇怪现象:抓取日志里,列表页被蜘蛛反复访问,但列表里的详情页几乎没被碰过。查看页面源代码才发现,详情链接并不在初始 HTML 里,而是等 JavaScript 执行后才出现。蜘蛛这次访问拿到的,更像一个空壳。
为什么初始 HTML 没有链接,会切断发现路径
搜索蜘蛛发现新 URL 的主要方式,是顺着当前页面 HTML 中可跟随的链接继续走。如果链接只存在于浏览器渲染后的 DOM 里,蜘蛛在抓取当前 HTML 时看不到它,后续访问就可能被推迟,甚至完全不做。
这不等于渲染后的页面一定不能被处理。不同搜索引擎、不同抓取场景对 JavaScript 的处理能力不一样,但把 URL 发现完全押在渲染上,风险偏高。尤其是列表页、分页、导航这类承担发现任务的页面。
哪些实现最容易让蜘蛛拿到空壳
- 列表内容由前端框架在客户端异步请求后渲染,初始 HTML 只有骨架。
- “加载更多”按钮通过点击事件追加内容,没有对应的静态分页链接。
- 轮播、标签页、折叠面板里的链接默认隐藏,需要交互才插入 DOM。
- 链接写成 div 或 span 加 onclick,没有可跟随的 a href。
- 服务器或 CDN 对蜘蛛返回了简化模板、空数据接口,或者缓存了错误版本。
- robots.txt 屏蔽了 JS、CSS 等渲染所需资源,导致页面无法完整执行。
先确认蜘蛛看到的和用户看到的是否一致
排查时不要只看浏览器里的页面,浏览器已经执行了脚本。更直接的做法是查看原始 HTML 响应,或者用命令行请求页面,观察返回内容里有没有目标链接。
- 用 curl 或查看源代码,搜索列表页响应中是否包含详情页 URL。
- 对比抓取日志:列表页访问次数与详情页被发现次数是否严重不成比例。
- 检查服务器日志里列表页的响应大小,异常偏小往往说明返回的是空壳或错误页。
- 确认 robots.txt 没有误挡渲染资源,也没有针对蜘蛛做特殊的空白返回。
- 用站点抓取工具模拟无 JS 环境,看看能走到第几层。
让关键链接回到初始 HTML 里
处理方向并不复杂:承担 URL 发现任务的链接,尽量在服务端输出的 HTML 中就能被跟随。
- 列表页、频道页、分页导航做服务端渲染,至少把前若干条和下一页链接直接输出。
- “加载更多”保留一个可访问的静态分页地址,不要只依赖按钮。
- 用真正的 a 标签和 href,不要用脚本事件代替链接。
- 重要详情 URL 可以同时放进 XML Sitemap,作为补充发现渠道。
- 保持内链结构稳定,别为了抓取把链接藏起来或只对蜘蛛显示。
渲染后可见,不等于抓取时可见。蜘蛛发现 URL 的起点,通常还是它拿到的第一份 HTML。
持续观察,而不是一次性修完
改完渲染方式后,抓取日志里的变化需要时间才能体现。可以按周观察:列表页响应大小、详情页被抓取的数量、新 URL 从发布到首次被抓取的间隔。如果列表页抓取正常但详情页仍然很少出现,就要回头检查内链、Sitemap 和服务器响应是否还有断点。
URL 发现不是单靠某一个设置完成的。服务器稳定返回完整 HTML,内链可跟随,Sitemap 作为补充,这三件事配合起来,蜘蛛走的路才会顺。