初识浏览器指纹:Selenium是如何被反爬的

2024-08-03阅读数:252

Selenium是一个用于Web应用程序测试的工具,通常称为模拟浏览器。经常被用在网络爬虫当中,爬取一些Ajax等动态调用、动态渲染的网页尤其好用。

但是selenium也不是万能的,很多人在使用selenium爬取网页时就会发现无法正常爬取网页内容,出现的现象有403 Forbidden、网页内容为空、网页内容凌乱等等。

其实出现以上的情况就是因为目标网站发现你在用selenium或类似的模拟浏览器进行爬取,简单来说就是被识别为爬虫了。

很多人不懂其中的原理,觉得selenium看起来就是一个浏览器,怎么就会被反爬了呢?

这就要从浏览器的技术原来讲起,浏览器有很多属性值是可以通过javascript代码来获取到的,识别selenium爬虫通常会获取以下几个属性值:

//注意区分大小
navigator.userAgent
navigator.webdriver
navigator.plugins

navigator.userAgent能够获取浏览器的User-Agent属性值,通常情况下selenium也会返回正常的值,但一旦爬虫需要在服务器上执行就会露出马脚:因为服务器通常不接显示器使用,然后就会把selenium设置为不显示界面的模式,这个时候User-Agent属性值就会带上“headless”这样的标识字符串。不显示界面的浏览器显然不是普通用户所使用的,所以就会被判断为爬虫。

if (navigator.userAgent.indexOf('headless') > -1){
    console.log('当前访问是爬虫。');
}        
else
{
	console.log('当前是正常浏览器。');
}

navigator.webdriver会返回一个布尔类型的值,意思就是检查当前浏览器是否为webdriver。如果是则返回true,否则返回false。正常使用的浏览器这一个属性值会返回false,但selenium默认会返回true,那网页只需要通过javascript判断一下这个属性值就知道现在来访问网页的是不是爬虫了。

if (navigator.webdriver){
    console.log('当前浏览器是webdriver,是爬虫。');
}        
else
{
	console.log('当前是正常浏览器。');
}

navigator.plugins会返回一个数组,里面是浏览器安装的插件名称。正常的浏览器即使是新安装的也会默认带一两个插件,但selenium就不一定。现在的selenium好一点,能够同步webdriver相同的浏览器的插件信息,所以写爬虫的时候基本不用处理这一项。

if ((navigator.plugins.length == 0)){
    console.log('当前访问是爬虫。');
}        
else
{
	console.log('当前是正常浏览器。');
}

知道了技术原理,那我们就可以找到应对方法了,以下为python示例代码:

# coding=utf-8
# 注意这里是以Chrome浏览器为例,请根据实际环境改成FireFox等
from selenium import webdriver

options = webdriver.ChromeOptions()

# 改变navigator.webdriver 属性值
options.add_argument('--disable-blink-features=AutomationControlled') 

# 改变navigator.userAgent属性值,如果不使用headless模式可以去掉这行代码
options.add_argument(
    'user-agent=Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36')

client = webdriver.Chrome(options=options)
client.get('https://spiderbuf.cn/list')

html = client.page_source
client.quit()

print(html)

通过options = webdriver.ChromeOptions()新建一个浏览器配置,然后通过加入参数 –disable-blink-features=AutomationControlled来去除selenium自动化测试的属性值,userAgent同理。

接下来就在生成selenium实例时把自定义的浏览器配置参数传递进去,就得到了自定义参数的selenium了。