Reprinted: https://www.cnblogs.com/xieqiankun/p/hide-webdriver.html
Many of my friends like to use Selenium + Chromedriver, thinking that it can do without being detected anti-crawler mechanism in the development of the site in reptiles.
I will not speak of this anti-Taobao reptile policies based on user behavior, just an ordinary little site with a single line of Javascript code, we can easily identify whether you are using Selenium + Chromedriver analog browser.
We look at an example.
Use the following piece of code which start Chrome window:
from selenium.webdriver import Chrome driver = Chrome()
Now open in this window, developer tools, and navigate to the Console tab, as shown below.
Now, in this window, enter the following code and press ENTER js:
window.navigator.webdriver
You can see, developer tools returned true
. As shown below.
However, if you open a normal Chrome window, execute the same command, this line of code can be found in the return value undefined
, as shown in FIG.
So, if the website for this parameter by js code, the return value undefined
note is normal browser, return true
instructions Selenium is used to simulate a browser. A quasi-one arrested. Js code example given here of a detection Selenium:
webdriver = window.navigator.webdriver; if(webdriver){ console.log('你这个傻逼你以为使用Selenium模拟浏览器就可以了?') } else { console.log('正常浏览器') }
网站只要在页面加载的时候运行这个js代码,就可以识别访问者是不是用的Selenium模拟浏览器。如果是,就禁止访问或者触发其他反爬虫的机制。
那么对于这种情况,在爬虫开发的过程中如何防止这个参数告诉网站你在模拟浏览器呢?
可能有一些会js的朋友觉得可以通过覆盖这个参数从而隐藏自己,但实际上这个值是不能被覆盖的:
对js更精通的朋友,可能会使用下面这一段代码来实现:
Object.defineProperties(navigator, {webdriver:{get:()=>undefined}});
运行效果如下图所示:
确实修改成功了。这种写法就万无一失了吗?并不是这样的,如果此时你在模拟浏览器中通过点击链接、输入网址进入另一个页面,或者开启新的窗口,你会发现,window.navigator.webdriver
又变成了true
。如下图所示。
那么是不是可以在每一个页面都打开以后,再次通过webdriver执行上面的js代码,从而实现在每个页面都把window.navigator.webdriver
设置为undefined
呢?也不行。
因为当你执行:driver.get(网址)
的时候,浏览器会打开网站,加载页面并运行网站自带的js代码。所以在你重设window.navigator.webdriver
之前,实际上网站早就已经知道你是
模拟浏览器了。
接下来,又有朋友提出,可以通过编写Chrome插件来解决这个问题,让插件里面的js代码在网站自带的所有js代码之前执行。
这样做当然可以,不过有更简单的办法,只需要设置Chromedriver的启动参数即可解决问题。
在启动Chromedriver之前,为Chrome开启实验性功能参数excludeSwitches
,它的值为['enable-automation']
,完整代码如下:
模拟浏览器了。
接下来,又有朋友提出,可以通过编写Chrome插件来解决这个问题,让插件里面的js代码在网站自带的所有js代码之前执行。
这样做当然可以,不过有更简单的办法,只需要设置Chromedriver的启动参数即可解决问题。
在启动Chromedriver之前,为Chrome开启实验性功能参数excludeSwitches
,它的值为['enable-automation']
,完整代码如下:
from selenium.webdriver import Chrome from selenium.webdriver import ChromeOptions option = ChromeOptions() option.add_experimental_option('excludeSwitches', ['enable-automation']) driver = Chrome(options=option)
此时启动的Chrome窗口,在右上角会弹出一个提示,不用管它,不要点击停用
按钮。
再次在开发者工具的Console选项卡中查询window.navigator.webdriver
,可以发现这个值已经自动变成undefined
了。并且无论你打开新的网页,开启新的窗口还是点击链接进入其他页面,都不会让它变成true
。运行效果如下图所示。
截至2019年02月12日20:46分,本文所讲的方法可以用来登录知乎。如果使用 Selenium 直接登录知乎,会弹出验证码;先使用本文的方法再登录知乎,能够成功伪装成真实的浏览器,不会弹出验证码。