做 URL 发现时,很多人会默认一件事:只要把链接投出去,搜索蜘蛛来了就能看到页面内容。但实际情况里有一类页面,蜘蛛确实来了,HTML 里却是空的——正文、商品信息、列表全靠浏览器执行 JavaScript 之后才出现。这种情况在抓取记录上是“来过”,实际拿到的却接近一张白纸。
先分清楚:是没抓,还是抓了没内容
这两种情况处理方式完全不同,所以先把日志和页面机制对上。
- 服务器日志里能看到搜索蜘蛛的访问记录,说明抓取链路是通的,问题出在返回内容上。
- 对比蜘蛛 UA 拿到的 HTML 和浏览器里看到的 DOM:如果源码里只有框架代码、几个 script 标签和空容器,基本就是客户端渲染。
- 有些抓取模拟工具可以关闭 JS 请求一次,看到的结果更接近搜索蜘蛛的第一眼。
常见的几种“看起来有内容、其实没有”的情况
1. 首屏完全靠客户端渲染
SPA 框架默认把内容放在打包后的 JS 里,服务端返回的 HTML 只有一个挂载点。搜索蜘蛛如果不执行 JS,或者执行得不完整,拿到的就是空壳。
2. 内容靠接口异步加载
页面框架先出来,数据再通过 XHR、fetch 请求填进去。这类页面即使能执行 JS,也取决于接口在抓取时是否正常响应、是否被 robots 拦住、是否需要鉴权。
3. 点击、滚动、切换标签才出内容
标签页切换、查看更多、懒加载列表都属于这一类。URL 不变,内容却要交互才出现,蜘蛛往往停在初始状态。
4. 链接是 JS 事件而不是 a 标签
如果站内跳转写成 onclick 或路由跳转,而不是可点击的 href,蜘蛛既拿不到内容,也很难顺着链接继续发现下一批 URL,URL 发现的效果自然打折。
投放前值得做的几项检查
- 查看页面“查看网页源代码”里的实际文本量,别只看浏览器渲染后的效果。
- 确认目标 URL 在关闭 JS 的情况下,是否至少能看到标题、简介、主要链接。
- 检查 canonical 配置是否规范,避免渲染前后两个版本互相打架。
- 确认接口地址没有被 robots.txt 屏蔽,否则渲染时数据也取不到。
- 确认页面不是必须登录、必须选择城市、必须带特定参数才显示内容。
判断标准可以简化成一句话:如果一个只读 HTML 的程序看不懂这个页面,搜索蜘蛛大概率也看不懂。
处理思路:让内容尽量出现在第一层
完全依赖搜索引擎执行 JS 来补内容,等于把主动权交出去。更稳的做法是把关键内容往前提:
- 服务端渲染或预渲染:让返回的 HTML 里就带正文和链接,JS 只做增强。
- 关键信息放静态部分:标题、价格、摘要、主要分类,优先写进初始 HTML。
- 导航用真实链接:用 a href 输出,既方便蜘蛛顺着爬,也方便做 URL 发现。
- 提供可访问的备用路径:比如为列表页提供分页静态地址,而不是只有无限滚动。
- 结构化数据补齐:JSON-LD 之类有助于机器理解,但不能替代正文本身。
投放节奏上的配合
JS 渲染的页面,抓取成本本来就比静态页高。投放时不要一次性把大批同类页面推出去,可以先小批量投、观察日志里返回的字节数和状态码,确认拿到的是有内容的响应,再逐步加量。如果发现蜘蛛频繁来访但页面始终是空壳,先停下来修渲染方式,别指望靠加投放量去“撞”结果。
另外,入口页最好放一些静态可读的内容和真实链接,这样蜘蛛从入口页进入目标页时,路径是清晰的;如果入口页自己也是 JS 渲染的空壳,链路从第一步就断了。
小结
URL 发现解决的是“蜘蛛知不知道这个地址”,能不能拿到内容则是另一层问题。遇到抓了却像没抓的情况,先别急着怀疑投放方式,花十分钟看看关闭 JS 之后页面还剩什么,往往就能定位到真正的原因。