做 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 之後頁面還剩什么,往往就能定位到真正的原因。