SEO爬虫报的死链和Googlebot抓的,从来不是同一批URL

SEO爬虫报的死链和Googlebot抓的,从来不是同一批URL
张文保 30 分钟阅读 3,423 阅读
本文目录
  1. 同一份HTML,为什么爬虫和浏览器数出来的链接不一样?
  2. 尾斜杠一个字符,能把整页链接指向别的地方吗?
  3. 十九条链接,十三条会变
  4. 为什么这件事比听起来严重
  5. 双斜杠入口更狠
  6. 兜底路由和相对链接凑一块会发生什么?
  7. 每深一层,链接跟着深一层
  8. 缺一不可
  9. 浏览器在解析href之前先做了什么?
  10. 那一行才是真正的杀手
  11. 为什么空格反而不剥
  12. 两套URL标准到底差在哪?
  13. 一百五十二格判决矩阵
  14. 差在哪几条
  15. 连“指向自己”都能算出两个答案
  16. 基准地址越畸形,两边差得越远
  17. Googlebot用的是哪一套?
  18. 现网到底有多少页面会踩这个?
  19. 但那9.5% 是满格伤害
  20. 顺手把自家站也测了
  21. 资源引用比链接更干净
  22. 那base标签为什么几乎没人用了?
  23. 怎么让四个裁判给出同一个答案?
  24. 第一条几乎解决全部问题
  25. 三条自查
  26. 保哥的判断
  27. 常见问题解答
  28. 我的死链检测工具报了一批404,站内却找不到这些链接,是怎么回事?
  29. 纯相对链接和根相对链接到底差在哪?
  30. href里的换行和制表符真的会出问题吗?浏览器不是会自动处理吗?
  31. 该不该给站点加base标签来统一基准地址?
  32. Googlebot到底按哪套标准解析链接?
  33. 两套URL标准并存,以后会统一吗?
  34. 协议相对链接(以 // 开头)现在还能用吗?
  35. 权威参考资料

摘要:把一份写着 href="api" 的HTML原封不动挂在两个都能返回200的地址下,浏览器算出来的目标链接不是同一个——十九条链接里有十三条会变。再往下拆,同一串字符要经过四道判决才变成一个可抓取的地址:HTML解析器先剥掉里面的换行和制表符,然后URL解析器按标准还原,而现在世面上跑着两套互不兼容的标准,实测一百五十二格判决矩阵有五十一格给出不同答案。最扎眼的一条是 htt<TAB>ps://example.com/x:浏览器把它读成一个跨站的绝对地址,而任何按属性原值取链接的爬虫都会把它当成本站的一个相对路径。谷歌自己声明按RFC 3986处理地址,渲染却跑在Chrome里,而Chrome用的是那套明确说要废弃RFC的标准。

上一篇同一个页面11种URL写法都返回200,做SEO查重复内容时一条都不会报数的是入口:一份内容到底有多少种地址能敲开服务器的门。这一篇数的是另一头——这些多出来的入口,会不会把页面上的链接也一起改掉。

结论提前说:会,而且比例高得不像话。

同一份HTML,为什么爬虫和浏览器数出来的链接不一样?

先把问题摆正。<a href="api"> 里的 api 不是一个地址,它是一个相对引用——一段需要配合“当前在哪儿”才能算出结果的字符串。从这段字符串到一个真正可以去抓的绝对地址,中间要过四道手:

顺序裁判它干什么谁在用
HTML解析器把属性值从字节流里取出来,顺手剥掉某些字符浏览器、渲染型爬虫
URL解析器把相对引用和当前地址合成绝对地址所有人,但用的标准不同
基准地址决定“当前在哪儿”取决于这个页面是用哪个地址打开的
服务器归一化请求到达后再改一次路径nginx及各类web服务器

四道手里,只有第四道是上一篇讲过的。前三道全在客户端,而你的SEO工具和Googlebot在这三道上未必是同一套实现

下面逐道拆,每一道都用实测说话。

尾斜杠一个字符,能把整页链接指向别的地方吗?

从第三道开始讲,因为它最容易验证,后果也最大。

上一篇实测出来,现网57.1% 的站尾斜杠两种写法都返回200,而且字节完全相同。也就是说 /docs/guide/docs/guide/ 很可能是同一份HTML的两个入口。

那么问题来了:这两个入口打开的同一份HTML,里面的链接指向哪儿?

十九条链接,十三条会变

我准备了一份包含十九种常见href写法的页面,分别用两个基准地址去解析,用的是Node 24内置的URL解析器(和浏览器同一套标准):

href写法基准带尾斜杠 /docs/guide/基准不带 /docs/guide
api/docs/guide/api/docs/api
./api/docs/guide/api/docs/api
../api/docs/api/api
api//docs/guide/api//docs/api/
.//docs/guide//docs/
../docs//
?x=1/docs/guide/?x=1/docs/guide?x=1
#frag/docs/guide/#frag/docs/guide#frag
/api/api/api(不变)
//example.net/apihttps://example.net/api同(不变)
https://example.org/apihttps://example.org/api同(不变)

完整矩阵十九条,其中十三条的解析结果不同,占68.4%

规则本身很简单:尾斜杠决定了“当前目录”是哪个。有尾斜杠时,当前目录就是 /docs/guide/;没有尾斜杠时,最后一段被当成文件名,当前目录退回 /docs/。相对引用是相对目录算的,所以整体平移了一层。

为什么这件事比听起来严重

把上一篇的数字接上来就明白了:

  • 57.1% 的站,两种尾斜杠写法都能返回200;
  • 这两个地址下发的是同一份HTML,字节级相同;
  • 可里面的相对链接,有68.4% 会解析到不同的地方。

于是同一份HTML在两个入口下,长出了两套不同的出边。爬虫从哪个入口进来,接下来走的就是完全不同的一条路——而且其中一条路上的地址多半是不存在的。

这解释了一类很常见但很难查的现象:站点地图里的页面收录得好好的,某些页面却总有一批来路不明的404,而你在站内怎么找都找不到那些链接。因为它们不在HTML里,是解析出来的。而当这些算错的地址又反过来占掉内部权重的流向时,就成了内链结构会自己烂掉:你辛苦攒来的权重正在漏进分页和重定向链里讲的那种慢性失血。

好在这个坑现网踩得不多,原因下面第六节会给数字——但踩上的那几个,是满格伤害。

双斜杠入口更狠

上一篇还测出21.9% 的站接受开头双斜杠 //a/b。这个入口对相对链接的杀伤力比尾斜杠更大:十九条里有十二条解析结果和规范入口不同,而且形态很难看——https://ex.com//docs/guide/api 这种带着双斜杠的地址会一路传染下去,因为它算出来的下一跳还是带双斜杠的。

上一篇讲过服务器为什么会收这种地址,配置侧的处置也在那篇的收敛表里。

兜底路由和相对链接凑一块会发生什么?

上一篇实验台上还有一条配置,当时只说了它造出无限个入口,没说这些入口拿来干嘛:

location / { try_files $uri $uri/ /app.html; }

这是前后端分离和单页应用的标准写法——文件找不到就交给应用。实测结果是任意深度、任意内容的路径全部返回200,而且是同一份字节。

现在把相对链接放进这份HTML里,两件事就咬合了。

每深一层,链接跟着深一层

同一份写着 href="api" 的HTML,在越来越深的路径下被打开:

页面被哪个地址打开href="api" 解析成
/docs/guide//docs/guide/api
/docs/guide/anything/docs/guide/api
/docs/guide/anything/deeper/still/docs/guide/anything/deeper/api

最后一行是关键:这个新算出来的地址,在兜底路由下同样返回200,同样是那份HTML,于是它又能解析出下一个更深的地址。

循环就此闭合。爬虫每走一步,就从当前页面拿到一个更深的地址;每一个更深的地址又都能打开、又都含着同一条相对链接。这就是老资料里说的“无限空间”,只不过它的成因通常被含糊地写成“动态生成的URL”,而实际上它是两个再普通不过的配置撞在一起的产物。

缺一不可

值得说清楚的是,这两个条件必须同时成立:

  • 只有兜底路由、没有相对链接:无限个地址确实存在,但没人给爬虫喂第一个,它们永远不会被发现;
  • 只有相对链接、没有兜底路由:算错的地址第二跳就撞404,爬虫走一步就停了,最多留下几条死链。

所以真正危险的是交集。好消息是这个交集在现网很小:兜底路由把不存在路径当200的站占3.8%,首页含纯相对链接的站占9.5%,两个条件同时踩上的概率不高。

但这也解释了为什么这类事故一旦发生就特别难查——它不是某一处配置写错了,是两处各自都合理的配置凑在了一起。单独审查任何一处都看不出问题,日志里则是一大片深度递增、从未见过的路径。服务器日志分析工具教程:读懂Googlebot抓取与预算浪费里讲的那种“抓取量涨了但收录没动”的形态,有一类源头就在这儿。

浏览器在解析href之前先做了什么?

现在回到第一道手。很多人默认“属性值里写的是什么,链接就是什么”,这个假设在有空白字符的时候会翻车。

我在真实Chrome里跑了一组:构造 <a href="...">,然后分别读两个东西——getAttribute('href')(属性原值)和 .href(浏览器解析后的绝对地址)。基准地址是 https://example.com/docs/guide/

属性里写的getAttribute 拿到浏览器实际去抓
apiapi/docs/guide/api
a\npi(中间一个换行)a\npi/docs/guide/api
a\tpi(中间一个制表符)a\tpi/docs/guide/api
a\rpi(中间一个回车)a\npi(回车被换成换行)/docs/guide/api
/foo\n/bar/foo\n/bar/foo/bar
htt\tps://ex.com/xhtt\tps://ex.com/xhttps://ex.com/x
a pi(中间一个空格)a pi/docs/guide/a%20pi

两列一对照,问题就出来了:属性原值和浏览器真正去抓的地址,是两个不同的字符串。

那一行才是真正的杀手

倒数第二行值得单拎出来。htt<TAB>ps://ex.com/x 这串东西,分成两种读法:

  • 浏览器:先把制表符剥掉,得到 https://ex.com/x,这是一个指向另一个站的绝对地址
  • 按属性原值处理的爬虫:看到的是 htt\tps://ex.com/x,它不以 http://https:// 开头,也不以斜杠开头,于是被归类成本站的一个相对路径,拼出来是 https://example.com/docs/guide/htt\tps://ex.com/x

同一行HTML,一个判成外链,一个判成站内死链。这已经不是“数字有偏差”了,是分类完全反了。

这个行为在WHATWG URL标准里写得明明白白:

If input contains any ASCII tab or newline, invalid-URL-unit validation error. Remove all ASCII tab or newline from input.

注意它的措辞:先报一个校验错误,然后照样把字符剥掉继续解析。所谓“校验错误”不是拒绝,只是记一笔,流程一步不停。

为什么空格反而不剥

最后一行的对照很说明问题:中间的空格没被剥掉,而是编码成了 %20。标准里剥的只有制表符和换行,以及首尾的空白,中间的空格属于“非法但要保留并编码”的一类。

所以这不是“浏览器会自动清理脏数据”这么简单的规律,它剥哪些、留哪些,是一张需要照着查的表,凭直觉猜必错。这类“看着是同一件事、实际分了好几档”的坑,在URI编解码器怎么用?中文URL编码、UTM参数转码与GSC乱码网址还原里还有一批。

顺带提醒一句:换行和制表符跑进href里,最常见的来源不是手写,是模板引擎。为了让生成的HTML好看一点而在属性值里换行缩进,浏览器毫无察觉,而你的链接审计报告可能已经炸了。

两套URL标准到底差在哪?

第二道手是重头戏。现在世面上并存着两套URL规范:

  • RFC 3986(也就是IETF STD 66),2005年的老规范,绝大多数服务端语言的标准库按它实现——Python的 urljoin、Java、Go、各类SEO爬虫框架;
  • WHATWG URL Standard,浏览器实际在用的那套,Chrome、Firefox、Safari、Node的 new URL() 都是它。

两套不是“新版旧版”的关系。WHATWG在自己的目标里写得很不客气:

Align RFC 3986 and RFC 3987 with contemporary implementations and obsolete the RFCs in the process.

直白说就是要把那两份RFC废掉。但RFC并没有被撤销,服务端生态还在按它跑。于是同一串字符,两边算出不同结果。

一百五十二格判决矩阵

我拿八个基准地址乘十九种href写法,共一百五十二格,同时跑Python的 urljoin(RFC 3986)和Node的 new URL()(WHATWG),逐格比对:

范围格数不一致比例
全部写法(含刻意构造的怪招)1525133.6%
只算日常会写出来的常规写法1041716.3%

就算只看日常写法,也有六分之一对不上。

差在哪几条

hrefRFC 3986算出WHATWG算出差别性质
\api/docs/guide/\api/api一个当普通字符,一个当斜杠
a\b/docs/guide/a\b/docs/guide/a/b凭空多出一层目录
%2e%2e/api/docs/guide/%2e%2e/api/docs/api编码的点段被还原成父目录
api␣(尾部空格)/docs/guide/api␣/docs/guide/api一个保留一个剥掉

第一行的落差最大:\api 在RFC那边是当前目录下一个名字带反斜杠的文件,在WHATWG那边直接跳到网站根目录。一个在三层深处,一个在最顶层,中间隔着整个站。

反斜杠这条在标准里也是“报错但照做”:

If c is U+005C (\), invalid-reverse-solidus validation error.

报完错,接着按斜杠处理。这个行为是为了兼容那些手滑把Windows路径分隔符写进href的历史页面,属于现实倒逼标准的典型。

连“指向自己”都能算出两个答案

有一组写法特别值得留意,因为它们看起来根本不该有分歧:href=""(空字符串,规范里表示“当前页面”)、href="?x=1"(只换查询串)、href="#frag"(只跳锚点)。这三种都是“还在这一页”的意思。

可只要当前页面是用一个含点段的地址打开的,比如 /docs/./guide/,两边就分家了:

hrefRFC 3986算出WHATWG算出
""/docs/./guide//docs/guide/
?x=1/docs/./guide/?x=1/docs/guide/?x=1
#frag/docs/./guide/#frag/docs/guide/#frag

差别在于WHATWG在解析阶段就把点段消掉了,而RFC 3986的合成算法在这几种“不改路径”的分支上直接沿用基准地址的原样路径,点段留在里面。

后果是:一个页面上指向自己的链接,在两套标准下指向两个不同的地址——其中一个还带着点段。而按上一篇的实测,带点段的地址在16.2% 的站上照样返回200。分页导航、语言切换、排序按钮这类控件大量使用 ?x=1 这种写法,一旦页面是从含点段的地址进来的,整组控件的目标地址就集体偏移。

这也是为什么把地址收敛干净是上游动作:基准地址一旦是规范形态,下游这些分歧全部消失。

基准地址越畸形,两边差得越远

按基准地址拆开看,不一致率不是均匀分布的:

基准地址十九格中不一致
/docs/guide/(规范形态)4
/docs/guide(无尾斜杠)4
/DOCS/GUIDE/(大写)4
/docs/./guide/(含点段)7
//docs/guide/(开头双斜杠)12
/docs//guide/(路径内双斜杠)12

规范形态下只有4格分歧,而双斜杠入口下飙到12格。原因是RFC那边会把多余斜杠归一化掉,WHATWG原样保留——而上一篇实测,21.9% 的站恰好接受这种双斜杠入口。

两篇的数据在这里合上了:服务器多开的那扇门,正好是两套标准分歧最大的那个位置。

Googlebot用的是哪一套?

这个问题的答案有点分裂,而分裂本身就是答案。

谷歌在URL结构文档里明确表过态:

Like any other HTTP client following IETF STD 66, Google Search's URL handling is case sensitive.

IETF STD 66就是RFC 3986。谷歌自称按RFC 3986处理地址。

但另一边,谷歌的渲染是跑在Chromium里的——网页被真实加载、执行JavaScript、构建DOM,然后从DOM里取链接。而Chromium的URL解析用的是WHATWG那套。

所以合理的推断是:抓取调度那一层按RFC 3986的语义处理地址(比如大小写敏感),而渲染阶段从页面里提取出来的链接,是Chromium按WHATWG算出来的。这个推断我没法直接验证——谷歌没有公开渲染管线取链接的实现细节,这里必须说清楚是推断而不是实测。

但对干活的人来说,可操作的结论是确定的:

凡是你用服务端爬虫(Screaming Frog之外的自研脚本、Python写的批量检查、CI里的链接校验)算出来的链接集合,都要假设它和渲染型爬虫算出来的不完全一样

这不是说工具不能用,是说报告里那些“莫名其妙的404”和“找不到来源的链接”,第一嫌疑人是解析差异,不是站点真的坏了。关于死链报告该怎么分诊、哪些必须修哪些可以放,修复死链对SEO到底有没有用?哪些必须修、哪些纯属白费功夫里有一套优先级;本文补的是它上游的那一步——先确认这条死链是不是工具自己算出来的。

现网到底有多少页面会踩这个?

讲了半天机制,得给个现实的量。我抓了181个站的首页,其中116个返回200且含链接,一共17988条 <a href>,按形态分类:

形态条数占比受基准地址影响吗
根相对 /path896549.8%
绝对 https://…821845.7%
片段 #x3031.7%
纯相对 path2801.6%
协议相对 //host/path1761.0%否(但会跨域)

真正受基准地址影响的纯相对链接,只占1.6%。按站看,116个站里只有11个(9.5%)首页含至少一条纯相对链接。

这个数字得诚实地讲:行业整体已经用根相对和绝对地址把这个坑绕过去了。写这篇之前我预期会看到一个更吓人的比例,实测没有。

但那9.5% 是满格伤害

相对链接的分布极度不均。中位数是0.0%,也就是一半以上的站一条都没有;可一旦有,往往是整站风格:

站点纯相对链接占比数量
mixpanel.com72.4%223 / 308
nginx.org66.0%35 / 53

这两个站首页上七成左右的链接是纯相对的。对它们来说,前面讲的所有解析差异全部生效,而且一次影响几百条链接。

结论因此是二元的,不是渐变的:绝大多数站完全不用管这件事,少数站需要当成头等大事。判断成本极低——打开首页源码,搜一下 href=" 后面第一个字符不是 / 也不是 h 的有多少条,一分钟出结果。

顺手把自家站也测了

写到这儿总得拿自己的站过一遍秤,不然只是在说别人。保哥这个站首页459条链接,形态是这样的:

页面链接总数绝对形态纯相对<base>href含换行或制表符
首页45945800
术语表页32829700

剩下的几十条是页内锚点。也就是说本站在这篇讲的每一个坑上都是零风险——不是因为特意治理过,而是因为模板一开始就是拿绝对地址拼的。这类问题的分布就是这样:要么一条都没有,要么满屏都是,中间地带很窄。

资源引用比链接更干净

顺手统计了 imgscriptlink 这三类标签的11542条引用:绝对地址67.0%、根相对26.2%、协议相对3.0%,纯相对只有0.5%

<a> 还干净三倍,不过协议相对的比例反过来更高(3.0% 对1.0%),那是全站HTTPS之前留下的历史习惯。想把自家站的链接结构整体扒一遍,内链外链分析器使用教程:一次扒清链接结构与SEO扣分项里那套统计口径可以直接照搬。合理——资源加载一旦出错是肉眼可见的白屏或者裂图,早就被修掉了;而链接指错只是多一个404,页面看起来一切正常。会立刻挨骂的问题总是修得更彻底,这条规律在哪儿都成立。

那base标签为什么几乎没人用了?

<base href> 是HTML里专门用来改基准地址的标签。理论上它能一劳永逸解决尾斜杠问题:不管页面被哪个地址打开,相对链接一律按 <base> 里写的算。

实测116个站里用了它的有两个,占1.7%。而这两个的用法都挺有意思:

站点<base href> 的值问题
php.nethttps://www.php.net/index.php指向一个具体文件,当前目录退回站根
angular.dev/值本身是相对的,还得先解析一次

第二个尤其绕:<base> 的作用是给别人当基准,可它自己的值又是个需要基准才能解析的相对地址。规范对这种情况有明确处理(拿文档地址来解析它),但读代码的人很容易看岔。

<base> 用得少不是因为它没用,而是因为它是个全局开关:一旦写上,页面里所有相对引用——链接、图片、脚本、表单提交地址——全部改基准。改对一个的同时可能改坏五个。相比之下,把链接写成根相对地址是局部的、可控的,代价也更低。

这也是为什么现网49.8% 的链接是根相对形态:它是唯一一种既省字数又完全不受基准地址影响的写法。

怎么让四个裁判给出同一个答案?

治理动作按投入产出排,从便宜到贵:

动作成本解决什么适用
链接一律写根相对或绝对基准地址的全部影响所有站,首选
尾斜杠301收敛到一种入口分裂的根源57.1% 的站需要
模板检查href里的换行缩进解析器分歧模板生成的页面
canonical写成绝对地址兜底,现网100% 已这么做所有站
审计工具换成渲染型两套标准的差异相对链接占比高的站
<base>基准地址基本不推荐

第一条几乎解决全部问题

值得强调:href="api" 改成 href="/docs/guide/api",这一个动作就让前三道裁判全部失效。根相对地址不依赖当前目录,尾斜杠怎么变都不影响它;也不存在点段要不要消除的分歧。

现网49.8% 的链接已经是这么写的,这不是什么前卫做法,是主流。顺带一提,同一份普查里116个站有98个写了canonical,形态百分之百是绝对地址,一个用相对写法的都没有——大家在这件事上早就达成共识了,只是没把同样的共识推到 <a href> 上。

三条自查

# 1. 首页有多少条纯相对链接(不以 / 和 h 开头)
curl -s https://你的域名/ | grep -o 'href="[^"/h][^"]*"' | wc -l

# 2. href 属性值里有没有换行或制表符
curl -s https://你的域名/ | grep -Pc 'href="[^"]*[\t\n][^"]*"'

# 3. 尾斜杠两个写法是不是都 200(是就要收敛)
curl -s -o /dev/null -w '%{http_code} %{size_download}\n' https://你的域名/某页面
curl -s -o /dev/null -w '%{http_code} %{size_download}\n' https://你的域名/某页面/

想省事也可以直接用现成的工具对照一遍,渲染对比器怎么用?揪出爬虫和用户看到的页面不一样讲的就是把两侧结果摆在一起看。

第一条如果结果是0,恭喜,这篇文章讲的坑你一个都踩不到,可以直接跳到最后。第三条两行如果状态码和字节数都一样,那就回上一篇看收敛配置。

顺带一提,相对路径算错这件事不只发生在HTML里。llms.txt校验器亮绿灯时,5条链接可能全是死的那篇碰到的是同一个毛病换了个文件格式:校验器只检查结构合不合法,不检查相对地址解析出来还在不在。

保哥的判断

这个话题很容易写成“你的工具全是错的、赶紧换渲染型爬虫”,但实测数据不支持这个结论。91% 的站首页一条纯相对链接都没有,对它们来说四个裁判永远一致,换工具纯属浪费预算。

真正值得做的是那个一分钟的自查:先确认自己在9.5% 里还是在90.5% 里,再决定要不要往下投入。技术SEO里最贵的浪费,从来不是没做优化,而是把资源投在了一个自己压根不存在的问题上。顺便说,那两个纯相对链接占比七成的站,一个是做用户行为分析的,一个是写出本文实验台那个服务器的——可见这事和团队水平无关,只和历史包袱有关。

常见问题解答

我的死链检测工具报了一批404,站内却找不到这些链接,是怎么回事?

先查两件事。一是这些地址是不是比正常路径少一层或者多一层目录,如果是,多半是尾斜杠导致的基准地址错位——同一个页面有带斜杠和不带斜杠两个入口,工具从其中一个进来解析相对链接,算出来的地址整体平移了一层。二是原地址里有没有反斜杠或者奇怪的空白,那属于两套URL标准的分歧。两种情况下站点本身都没坏,坏的是链接是怎么算出来的。

纯相对链接和根相对链接到底差在哪?

href="api" 是纯相对,结果取决于当前页面的地址,尾斜杠变一下结果就变。href="/docs/api" 是根相对,只依赖域名,当前页面在哪儿都不影响。现网49.8% 的链接用根相对,纯相对只有1.6%。如果你只想记一条规则,就记这个:href的第一个字符是斜杠,你就安全了。

href里的换行和制表符真的会出问题吗?浏览器不是会自动处理吗?

浏览器确实会剥掉它们,WHATWG标准明确要求“Remove all ASCII tab or newline from input”。问题出在按属性原值取链接的工具上——它拿到的是没剥过的字符串,于是算出一个完全不同的地址。最极端的例子是制表符落在协议名里,浏览器读成跨站绝对地址,工具读成本站相对路径,分类直接反了。中间的空格则两边都不剥,会编码成 %20。

该不该给站点加base标签来统一基准地址?

一般不建议。它是全局开关,会同时影响页面里所有相对引用,包括图片、脚本和表单提交地址,改对链接的同时容易改坏别的。现网116个站里只有2个在用。把链接改写成根相对地址是更便宜也更可控的做法,效果完全一样。

Googlebot到底按哪套标准解析链接?

谷歌文档里明确说自己的URL处理遵循IETF STD 66,也就是RFC 3986,这解释了它为什么大小写敏感。但渲染阶段跑在Chromium里,而Chromium用的是WHATWG那套。合理推断是两层各用各的,不过谷歌没公开渲染管线取链接的实现细节,这一条是推断不是实测。干活时按最保守的假设来:不要指望自研脚本算出的链接集合和渲染型爬虫完全一致。

两套URL标准并存,以后会统一吗?

短期看不会。WHATWG在自己的目标里写着要让那两份RFC作废,但RFC 3986并没有被正式撤销,服务端语言的标准库还在按它实现,而且改动它会破坏大量既有系统。更现实的做法是承认分歧存在,在会出问题的位置(相对链接、反斜杠、编码的点段)主动避开,而不是等标准统一。

协议相对链接(以 // 开头)现在还能用吗?

能用,但没必要。它在全站HTTPS之前有意义——让资源跟随当前页面的协议。现在所有站都上了HTTPS,直接写 https:// 更清楚。它本身不受基准地址影响,所以不属于本文讲的这类问题,但它有另一个坑:// 开头的地址会跳到另一个主机,一旦域名写错就是跨域,而这个错误在代码审查里看着特别像一个普通的路径。

权威参考资料

分享到
标签
版权声明

本文标题:《SEO爬虫报的死链和Googlebot抓的,从来不是同一批URL》

本文链接:https://zhangwenbao.com/relative-url-resolution-crawler-googlebot-broken-link-seo.html

版权声明:本文原创,转载与引用请注明作者与原文链接。许可协议: CC BY 4.0

继续阅读
发表评论
分享到微信 或在下方手动填写
支持 Ctrl + Enter 提交