百度结果页 链接点击后到进入目标页面都发生了什么?
搜索结果页面上的一个点击,比你想象的要复杂,当点击百度搜索结果的链接后,你将会被带去一个第三方网页。这一简单的过程其实相当复杂,那么你是否了解在这几百毫秒之中发生了些什么呢?
记录点击行为
这一过程通过调用一个w.gif的像素图片完成。这个图片会传递一些参数,详见下图。
此处的检索词是“关键字”,点击的结果是“百度指数”这条结果。url里就是中间页的链接,这个链接里?url=后面的值之后还会被用到。path里是百度当前结果页的地址。另外resource id为1599,说明是个自然搜索结果。至此,百度已获取该点击信息。
从referer剥离参数wd
接下来百度会进行一步操作,这步操作将会隐去用户具体检索的关键字。举个例子,我在百度搜google,那么URL将是https://www.baidu.com/s?wd=google
当我点击第一个谷歌香港的结果后会跳去一个百度的中间页面,这个中间页面的URL是:https://www.baidu.com/link?url=_qzTpXb2Yx6i8OvjybEol7DExwdmEjiEGCwsqKZ-38gGFi93MVamdx5ncxor-ayz&wd=&eqid=9fd2c68f0006060f000000045adc8632
百度请求这个中间页时,会用该中间页的URL作为referer的URL。这个URL并不是点击时产生的,但是referer的URL却是点击时赋予的。你会发现wd=后的值为空,而wd后放置的是检索词信息,这就是为什么你在Google Analytics中看不到用户检索词的原因。
至此,百度很好地“保护了用户的隐私”。
新窗口打开中间页面
第三步是在新窗口中打开这个中间页面,至于为什么不是像谷歌或者必应那样在原窗口打开,这关系到中国网民的习惯问题。至少自从有target=”_blank”那年起,国内的搜索引擎就是这么玩的。或许检索效率不高还需回头点别的结果或者使用其他搜索词吧。但是由于新打开窗口,出现了一些安全隐患,我们在后面详述。这个中间页基本上就是一个脚本。整理格式后,请见下图:
我们看到,这个脚本用了window.location.replace来进行跳转到目的地网址。这是一个常见的JS跳转。
至此,百度新开了一个窗口并将要带你去目的地网页。
验证点击真实性
我们注意到,百度在这个中间页调用了window.opener.bds.pdc.sendLinkLog(); 回到搜索结果页,我们会发现这个页面调用了一个JS。详见下图:
我们看到这个请求发送了中间页的字符串参数作为url的值,如果没有这个请求以及没有之前w.gif的请求,那么这个点击很有可能是假的。虽然不能杜绝虚假模拟点击,这很大程度上过滤掉了许多爬虫和低级的虚假点击。
至此,百度为点击数据真实性加了“双保险”。
剥离Opener,保障安全
在中间页代码的最后我们看到了window.opener=null; 这行代码如果不加,那么跳转到目标页后目标页就可以凭着window.opener对百度搜索结果页面进行各种操作。新规范HTML中虽然已经增加了rel=noopener这样的属性来避免对opener赋值,但是旧版的浏览器并不支持。旧版浏览器只支持noreferrer,但是百度还是很自豪地想告诉目标页“这是我度娘给您送的免费流量”的。总之,这就造成了安全隐患。在脚本的最后将opener赋为空值就是出于安全的考虑,同时保留了referrer。
至此,百度已经准备好带你去目标页面了。
跳转到目标页面
经过了上述五步的铺垫,百度终于可以带你去目标页面了。这个页面在新窗口中,它无法获取访客所检索的检索词,它无法对打开它的百度搜索结果页窗口进行操作。
至此,我们已经介绍完了。我们介绍百度点击的目的只是想说明百度在数据和安全上确有周全的考虑,作为SEO,我们还是尽量从根本着手,避免做一些为了欺骗引擎吃力不讨好的事情。
对于本文提到的rel=noopener,您可以参考:https://developers.google.com/web/tools/lighthouse/audits/noopener?hl=zh-cn
另外referrer丢失的原因有很多,建议看W3的官方文档: https://w3c.github.io/webappsec-referrer-policy/