蜘蛛读链接,只认 href 里那串最终地址
搜索引擎蜘蛛解析 HTML 时,关注的不是链接看起来像不像链接,而是 href 属性里最终得到的那个字符串。浏览器会替用户纠正很多模糊写法,蜘蛛的解析过程更接近“按规则照做”:规则清楚就往前跟,规则不清楚就放弃。所以链接写法上的细节,常常决定一个 URL 能不能进入抓取队列。
相对路径能用,但要留意 base 标签
相对路径(例如 /list/1.html、../about.html)蜘蛛能正常解析,前提是它知道当前页面的基础地址。大多数情况下这个基础地址就是页面自身的 URL,但如果页面头部出现了 base 标签,所有相对路径都会以 base 里的地址为基准计算。
历史上因为 base 写错、或者复制模板时忘了改,导致整站内链指向错误目录甚至别的域名的情况并不少见。对蜘蛛来说,这类问题的后果不是“抓不到”,而是“抓错”:它会顺着错误地址去请求,可能拿到 404,也可能在别的路径下发现一批并不存在的 URL。
稳定起见,关键导航、面包屑、Sitemap 里的地址尽量写成绝对 URL,路径细节不容易被模板层级影响。
大小写与结尾斜杠:两个地址,还是同一页
路径大小写
域名部分大小写不敏感,路径部分在多数服务器上是敏感的。/News/1.html 和 /news/1.html 在 Linux 环境下通常是两个不同资源。如果站内链接一会儿大写一会儿小写,蜘蛛就会把它们当成两个 URL 分别抓取,日志里也会留下两份记录。统一成小写是最省事的做法。
结尾斜杠
/about 和 /about/ 是否算同一页,取决于服务器配置。有的返回 301,有的两个地址都返回 200。如果两种情况都存在,等于给同一份内容制造了两个入口。建议全站保持一种风格:目录型地址带斜杠,文件型地址带扩展名。
共同点是重复,不是打不开
上面两类问题的共同点在于:页面没有坏,只是被拆成了多个地址。抓取预算有限,同一内容被抓两遍,真正的新页面就少了一次机会。
井号后面的内容,蜘蛛基本不参与
URL 里 # 之后的部分叫片段标识,浏览器用它做页内定位,但不会把它发给服务器——因为请求里根本没有这一段。蜘蛛也不会把 #section 当成一个新 URL。
- 普通锚点如 #comment,只影响页面定位,不影响抓取。
- 用 #!/detail?id=1 这类 hash 路由组织的页面,蜘蛛最初看到的是 # 前面的地址,后面的内容是否出现,取决于它是否执行脚本、以及脚本渲染得对不对。
- 想保证可抓取,尽量使用真实路径(/detail/1),而不是靠 # 切换内容。
转义与编码:空格、中文与 & 符号
链接里出现空格、中文、& 等字符时,需要按规则编码。常见的坑有:
- 空格写成 %20;写成 + 只在查询字符串中表示空格,放在路径里含义不同。
- 中文字符编码后是一串 %E4%...;如果不同位置的链接有的用原始中文、有的用编码形式,服务器可能视为两个地址。
- HTML 属性里的 & 最好写成 &。直接写单个 & 有时仍能解析,但在部分解析器里可能被截断,导致后面的参数丢失。
- 参数顺序不同(?a=1&b=2 与 ?b=2&a=1)服务器往往认为是同一页,但对蜘蛛来说是两条字符串,需要靠规范化处理。
不要用脚本代替 href
把一个可点击入口写成 a 标签加 onclick 跳转、href 却填 javascript:void(0),等于把人能点的入口变成蜘蛛看不见的入口。类似的还有用 div 加点击事件、用 span 做按钮、图片外面没有链接。
只要不是 a 标签的 href,或者 href 里没有真实地址,蜘蛛通常不会把它当成发现 URL 的路径。如果确实需要脚本跳转,至少保留一个指向目标地址的 a 标签,脚本只做体验增强。
容易被忽略的一类字符
- 零宽空格、全角空格、全角问号混进 href,肉眼看不出来,链接直接失效。
- 从后台编辑器或文档软件粘贴时,英文引号被替换成中文引号,属性解析出错。
- 换行符、制表符插在 URL 中间。
- URL 中出现分号或逗号,在部分服务器上会被当作路径参数处理。
怎么自查
- 抓取几十个典型页面,把 href 提取出来列成表格,看有没有大写路径、双斜杠、错误的 base 影响。
- 在服务器日志里找同一内容的多个地址变体,看它们是否都在被抓。
- 核对 Sitemap 里提交的地址与实际内链指向的地址是否一致。
- 对带参数的页面,确认哪些是筛选产生的、哪些是可以长期存在的,再决定怎么收敛。
链接写法规范化的收益,不体现在某一次抓取上,而体现在长期:蜘蛛每次来都少走一点弯路,省下来的额度才会回到真正的新内容上。
URL 写法不是排版问题,而是蜘蛛理解站点结构的第一层输入。把这些细节提前统一,比事后用各种规则去补救要轻松得多。