蜘蛛顺着链接走,链接在哪儿,抓取路径就延伸到哪儿。但很多站点把入口藏在了「点击之后」——按钮、下拉菜单、JavaScript 路由。对抓取来说,这些位置等于没有链接。下面梳理这类入口的形态、排查方法和改造顺序。
哪些入口属于「点击才出现」
- 「加载更多」按钮:首屏只渲染十条,剩余条目靠点击后请求接口再插入页面。
- JS 路由:菜单项绑定的是脚本跳转,地址栏变化由前端完成,初始 HTML 里没有对应地址。
- 下拉菜单与折叠面板:子分类地址在悬停或展开后才进入 DOM。
- Tab 切换:只渲染当前标签的内容,其余分类的链接在初始页面里根本不存在。
- 整块卡片点击跳转:绑定了点击事件,但没有可识别、可复制的地址。
抓取程序看到的是什么
抓取程序拿到的是服务器返回的 HTML,或者渲染之后的 DOM。前者不含脚本生成的链接,后者取决于渲染是否成功、异步请求是否跑完。常见的写法里,「可点击」和「可抓取」是两件事:button 元素没有 href,href 填一段脚本代码不是有效地址,data-href 只是自定义属性,写在点击事件里的跳转逻辑对链接解析没有意义。
结果就是:页面在人眼里完整,在抓取路径里却是一堵墙。列表翻到第二页之后、折叠起来的子分类、Tab 里的商品列表,全都停在墙外,只能靠别处的链接偶然被带到。
怎么确认自己踩了这个坑
- 关闭 JavaScript 加载页面,或直接查看渲染前的源码,看看导航和分页还剩多少可点链接。
- 对照抓取日志:某个栏目如果只有首页有记录,第二页往后完全没有访问痕迹,多半是入口问题,而不是内容问题。
- 统计页面数量与指向深层页面的链接数量,两者差距悬殊时值得警觉。
- 随便挑一个深层地址,问自己:从首页出发,纯靠普通链接几步能到?如果答案是「到不了」,问题就确认了。
改造顺序
- 主入口改成真实链接。导航、分页、分类、上一页下一页,都用带 href 的链接,脚本只做增强,不做唯一通道。
- 分页保留可独立访问的地址。点击「加载更多」之后,列表也应该对应一个能直接打开的相对地址,比如带 page 参数或 /page/2/ 的形式。
- 折叠和 Tab 内容尽量预渲染。至少让子分类和代表性链接出现在初始 HTML 中,再用样式隐藏。
- 服务端渲染或预渲染关键页面。渲染失败时要有可读的降级内容,而不是一个空容器。
- 用 Sitemap 兜底,但别当替代品。Sitemap 能说明有哪些地址存在,内链才决定抓取的先后与路径走向。
几个容易忽略的细节
一是「下一页」只在滚动到底部时才出现,抓取程序到不了那个位置;二是无限滚动没有终点,也没有可枚举的地址;三是筛选条件靠脚本拼接,用户看得到、抓取程序拿不到;四是顺手给分页链接加了 nofollow,等于自己把路封上。
链接的价值不在于样式上能不能点,而在于 HTML 里是否存在一个明确的地址。把入口写成地址,是 URL 发现中最省事的一步。
如果不打算大改前端,可以先把最重要的三五个入口——主导航、栏目分页、详情页推荐位——改成真实链接,再逐步处理 Tab 与折叠区域。改动之后观察抓取日志里深层地址的出现情况,比反复猜测更有效。