一日一技:为什么网站知道我的爬虫使用了代理?

在公众号粉丝群里面,经常有同学问:为什么自己的爬虫明明设置了代理,但一访问网站就能被发现。我总结了几种常见的情况。

实际上,网站要识别你是否使用了代理,并不一定非要什么高深的反爬虫机制,也不需要使用AI识别用户行为。下面这几种情况,要识别代理简直是易如反掌。

你根本没有使用代理

有一些初学者在使用Requests请求网站的时候,是这样写的代码:

1
2
3
4
5
6
7
8
import requests

resp = requests.get('https://httpbin.org/ip').text

print('不使用代理:', resp)

resp = requests.get('https://httpbin.org/ip', proxies={'http': 'http://IP:port'}).text
print('使用代理:', resp)

运行效果如下图所示:

为什么使用了代理以后,IP没有变呢?这是很多刚刚使用Requests的同学常常犯的错误。因为你根本没有给https网站使用代理,你的代理只会对http网站生效。要对https网站生效,需要给它指定代理:

1
resp = requests.get('https://httpbin.org/ip', proxies={'http': 'http://IP:port', 'https': 'http://IP:port'}).text

P.S.: 注意看上面的代码,给https网址设置代理的时候,key是https,但值依然是http://开头。对一些代理供应商来说,如果你把这里设置成了https://开头,就会报错。不过这个原理跟本文无关,就暂时不讲了。如果大家有兴趣的话,我再写一篇文章来讲。

你的代理IP是服务器IP

有很多代理供应商,他们批量采购云服务器来搭建代理服务。例如国内的供应商会采购阿里云、腾讯云、华为云的服务器来搭建代理。海外的供应商会采购AWS或者Google云服务器。

如果你在云服务器上跑过不加代理的爬虫,你会发现,有时候一个爬虫,不加代理,在自己电脑上跑一点问题都没有,但是在云服务器上一跑就会被识别。这是因为云服务器的IP地址范围跟家用宽带是不一样的。

像AWS和Google云,他们的云服务器IP范围是公开的,只要网站提前把来自这个范围的所有请求全部禁掉,那么从AWS、Google云服务器上面发起的请求直接就会被当做爬虫请求。因此搭建在上面的代理服务自然就不会生效了。

国内的云服务供应商的服务器IP地址是否公布过我不太清楚,但他们的IP范围肯定是跟家用IP不一样的。网址遇到来自这些可疑IP范围的请求时,虽然不一定完全封禁,但是弹一个验证码出来测一测,还是可以挡住很多爬虫。

遇到这种情况,爬虫只有设法采购一些使用家用宽带搭建代理服务的供应商,才能解决问题。但这种代理价格肯定会翻好几倍。

你的代理IP不是高匿代理

代理IP有三种常见的类型,透明代理,匿名代理和高匿代理。

使用透明代理的时候,网站可以同时看到代理IP和你的真实IP。用了等于白用。

使用匿名代理的时候,网站看不到你的真实IP,但是在请求里面有一个特征,可以告诉网站,你正在使用代理访问。

而只有真正的高匿代理,才能把你的爬虫请求隐藏起来。

有一些同学可能会从网上搜索免费的代理IP来使用。但这里面很多代理并不是高匿代理。肯定会被发现。

服务器供应商的IP池被污染

有些人的爬虫写得非常垃圾,自以为有代理就无所畏惧,爬虫请求漏掉百出,网站即使不检查IP频率,也可以从其它特征知道这是爬虫请求,于是网站就会连带着这个代理IP一起封掉。而偏偏这种垃圾爬虫的请求速度又极快。哪怕代理供应商的IP池中有几百万个IP,也会很快被这些垃圾爬虫全部害死。

国内头部网站每天都会被数以千万计的爬虫请求访问,而主流的代理供应商就那么几家。如果很多垃圾爬虫都选中了同一家供应商,而他们的代理池更新又不及时。那么你使用了这家供应商的代理IP,自然一来就会被发现。

代理不支持HTTP/2

有一些网站需要使用HTTP/2请求。在Python里面,已经有不少HTTP客户端库支持发起HTTP/2的请求了,例如httpx。但是,现在很少有代理供应商能提供支持HTTP/2的代理,因为它搭建起来比较麻烦。于是,当你使用了支持HTTP/2的客户端,通过一个HTTP/1.1的代理IP访问一个HTTP/2的网站的时候,网站并不能正常返回内容。

总结

网站要检测爬虫有非常多的方法,要检测一个请求是不是使用了代理来发起,也有很多种方法。而且这些方法并不需要什么高深的技术,一个初级工程师都能写出来。

那些自以为给爬虫加了代理就可随便爬网站的人,你们不仅害了自己,还害了别的爬虫。