發現的前提是地址能被当作獨立頁面
URL 發現這件事,很多时候不是蜘蛛不愿意抓,而是它根本没把某個地址当成一個頁面来看。前端路由常见的两種寫法——哈希模式和歷史模式——在這一点上差別很大,但不少站点把它們当成一回事,结果就是頁面在站内点得到,却迟迟没有獨立的抓取记錄。
哈希地址長這样:example.com/#/list/2。浏览器發起請求时,井号之後的内容不會發送给服務器,服務器永遠只看到 example.com/ 這一层。對蜘蛛来说,站内所有哈希路由都指向同一個资源,無法作為不同 URL 被分別發現。即便頁面上有完整内容和可点連結,這些内容也很难進入獨立的抓取與索引流程。
歷史模式看起来正常:example.com/list/2。它确實是獨立路径,但是否能被發現,取决于两件事:服務器能不能對该路径直接返回頁面,以及源碼里有没有可跟随的連結。
歷史模式的三個常见坑
直连返回 404
單頁應用通常把路由交给前端處理,服務器只配置了根目錄。蜘蛛拿着 /list/2 這個地址去直连时,服務器找不到對應文件,返回 404。它不會因為你在站内点击能打開就認為這個地址有效,404 就是 404。要解决就得在服務器端配置回退,让前端路由路径统一返回入口頁面,並给出 200 狀態碼。
源碼里只有 onclick
很多列表是這样寫的:一個 div 或 span,绑定点击事件後調用路由跳轉。這種做法對人没問题,對蜘蛛就不行——HTML 源碼里没有 href,解析阶段看不到這條邊。除非它愿意执行 JavaScript 並等待渲染完成,否則這個入口等于不存在。把可点击元素換成真正的 a 标簽,寫上完整 href,是最省事的改法。
渲染依赖被挡住
就算蜘蛛愿意渲染,JS 文件、接口請求、样式字体這些资源如果被 robots.txt 拦了,或者在超时時間内没能返回,渲染出来的頁面就是空的,連結自然也拿不到。检查一下 robots.txt 里有没有誤挡静態资源目錄,以及接口响應時間是否够稳定。
自查顺序:從源碼到日誌
- 用 curl 或查看網頁源代碼的方式取一次 HTML,搜尋關键路径是否出現在 href 里。要看初始源碼,渲染後的 DOM 不算數。
- 直接訪問几個深层路径,確認狀態碼是 200,而不是 404 或被重定向到首頁。落到首頁同样會让蜘蛛認為该路径没有獨立内容。
- 在服務器日誌里筛出蜘蛛的訪問记錄,看它有没有真的請求過這些路径。請求過但狀態異常,和压根没請求,是两類問题,處理方向完全不同。
- 把關键路径寫進 Sitemap 作為补充入口,但不要把它当成萬能兜底——Sitemap 只提供發現线索,能不能抓仍然取决于响應狀態和頁面内容。
更稳妥的结构選擇
如果内容和流量依赖搜尋,列表頁、詳情頁這類核心頁面尽量走服務端渲染或静態生成,让 HTML 直出时就有完整連結和内容。前端路由可以用在交互密集、對發現不敏感的部分,比如後台、設定頁、彈窗流程。
另外,站内至少保留一條纯 HTML 的導航路径:底部導航、栏目列表、相關推荐,用 a 标簽直接列出。這條路径不依赖脚本,哪怕前端渲染环节出問题,蜘蛛仍然有路可走。
判断标准很简單:把 JavaScript 關掉,頁面上的連結還能不能点、能不能跳。不能的话,URL 發現這一环就要打個問号。