当前位置:首页 > 综合

不支持的Web服务器检测

你访问一个网站,不支浏览器白屏,检测控制台里蹦出一行红字:Unsupported web server detection。不支这不是检测你网断了,也不是不支网站挂了,而是检测服务器在告诉你——它不认识你递过来的“名片”。

说白了,不支HTTP协议里有个叫User-Agent的检测请求头,浏览器每次访问都会带上它,不支里面写着“我是检测Chrome,版本120,不支跑在Windows上”。检测服务器收到之后,不支会根据这个信息决定怎么回应。检测有些服务器还会进一步检测Server头、不支TLS指纹、甚至TCP窗口大小,来判断你到底是正常浏览器还是爬虫脚本。当这些检测逻辑遇到一个它没见过的组合,就会抛出“不支持的Web服务器检测”这个错误。

我上周就撞上了。用Python的requests库去抓一个电商站点的商品页,代码写得规规矩矩,加了User-Agent,加了Referer,结果返回403,页面内容是一段JSON:{ "error":"unsupported web server detection"}。换成浏览器打开同一个URL,一切正常。问题出在哪?我用curl -v对比了一下请求头,发现浏览器发过去的Accept-Language、Accept-Encoding、Connection这些字段的顺序和值,跟requests默认发的完全不一样。服务器那边八成是拿了一套指纹库,逐个字段比对,差一个就判定为“非标准客户端”。

这种检测机制其实挺常见的。Cloudflare的Bot Management、Akamai的Bot Manager、还有AWS WAF,都有类似逻辑。它们不只看User-Agent,还会看sec-ch-ua系列头、HTTP/2的帧顺序、TLS握手里的JA3指纹。你用requests或者httpx直接发请求,TLS指纹跟Chrome差得远,服务器一眼就能认出来。这时候它不会直接封你IP,而是返回一个“不支持的Web服务器检测”之类的模糊错误,让你摸不着头脑。

那怎么绕过?最笨的办法是用Selenium或者Playwright驱动真实浏览器,但慢,吃内存。稍微聪明点的做法是用curl_cffi这个库,它底层用curl-impersonate,能模拟Chrome的TLS指纹和HTTP/2帧。我试了一下,把requests换成curl_cffi.requests,其他代码不动,那个电商站点立刻返回200。还有个更轻量的方案:用tls-client,它封装了Go的utls库,也能伪造JA3。不过这些工具更新频率得跟上,Chrome每升级一次TLS指纹就变,你的模拟库也得跟着改。

反过来看,如果你是自己搭服务器,想加这种检测,别自己写。用现成的WAF规则或者Cloudflare的Bot Fight Mode,省事得多。自己写的话,很容易误伤——比如某些企业内网的老旧浏览器,User-Agent里带一堆奇怪的后缀,你的正则匹配不到,就把正常用户挡在外面了。我见过一个案例,某政府网站用了某国产WAF,结果所有用Firefox ESR版本的用户全被拦,错误页就是“不支持的Web服务器检测”。后来查出来是WAF的指纹库太旧,不认识Firefox 115的TLS扩展顺序。

所以下次再看到这个错误,别急着骂网站。先打开开发者工具,对比一下浏览器和你的脚本发出的请求头,再查查TLS指纹。十有八九,问题就出在那些你没注意到的细节里。

分享到: