在用Chromeriver测试Selenium,我注意到有些页面可以检测到您正在使用Selenium,尽管根本没有自动化。即使我只是在手动浏览时,只要通过Selenium使用Chrome,我也经常会看到一个页面,上面说检测到了可疑的活动。我检查了我的用户代理和浏览器指纹,它们都与普通的铬浏览器完全相同。
当我以普通浏览这些站点时,一切都很好,但是使用Selenium的那一刻我就被检测到了。
理论上,自动化操作Chrome在任何Web服务器上看起来都应该完全相同,但不知怎么的,它们可以检测到。
使用selenium模拟浏览器进行数据抓取无疑是当下最通用的数据采集方案,它通吃各种数据加载方式,能够绕过客户JS加密,绕过爬虫检测,绕过签名机制。它的应用,使得许多网站的反采集策略形同虚设。由于selenium不会在HTTP请求数据中留下指纹,因此无法被网站直接识别和拦截。
这是不是就意味着selenium真的就无法被网站屏蔽了呢?非也。selenium在运行的时候会暴露出一些预定义的Javascript变量(特征字符串),例如"window.navigator.webdriver",在非selenium环境下其值为undefined,而在selenium环境下,其值为true(如下图所示为selenium驱动下Chrome控制台打印出的值)。
我所要做的一切是为了确保$cdc_不再以文档变量的形式存在,而voila(下载chromeriver源代码,修改chromeriver并重新编译)。$cdc_以不同的名称) 这是我在chromeriver中修改的函数:
调用函数.js:
function getPageCache(opt_doc) {
var doc = opt_doc || document;
//var key = '$cdc_asdjflasutopfhvcZLmcfl_';
var key = 'randomblabla_';
if (!(key in doc))
doc[key] = new Cache();
return doc[key];}
(我所做的一切$cdc_到randomblabla_.
下面是一个伪代码,它演示了BOT网络可能使用的一些技术:
runBotDetection = function () {
var documentDetectionKeys = [
"__webdriver_evaluate",
"__selenium_evaluate",
"__webdriver_script_function",
"__webdriver_script_func",
"__webdriver_script_fn",
"__fxdriver_evaluate",
"__driver_unwrapped",
"__webdriver_unwrapped",
"__driver_evaluate",
"__selenium_unwrapped",
"__fxdriver_unwrapped",
];
var windowDetectionKeys = [
"_phantom",
"__nightmare",
"_selenium",
"callPhantom",
"callSelenium",
"_Selenium_IDE_Recorder",
];
for (const windowDetectionKey in windowDetectionKeys) {
const windowDetectionKeyValue = windowDetectionKeys[windowDetectionKey];
if (window[windowDetectionKeyValue]) {
return true;
}
};
for (const documentDetectionKey in documentDetectionKeys) {
const documentDetectionKeyValue = documentDetectionKeys[documentDetectionKey];
if (window['document'][documentDetectionKeyValue]) {
return true;
}
};
for (const documentKey in window['document']) {
if (documentKey.match(/$[a-z]dc_/) && window['document'][documentKey]['cache_']) {
return true;
}
}
if (window['external'] && window['external'].toString() && (window['external'].toString()['indexOf']('Sequentum') != -1)) return true;
if (window['document']['documentElement']['getAttribute']('selenium')) return true;
if (window['document']['documentElement']['getAttribute']('webdriver')) return true;
if (window['document']['documentElement']['getAttribute']('driver')) return true;
return false;};
根据经验,还可以简单地在十六进制编辑器(推荐使用UltraEdit)中打开chromedriver.exe,只需手动进行替换,而无需实际进行任何编译。查找 $cdc_asdjflasutopfhvcZLmcfl_ 替换成内容等长的字符即中。