Python 当您在 chromedriver 中使用 selenium 时,网站可以检测到吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33225947/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 13:02:50  来源:igfitidea点击:

Can a website detect when you are using selenium with chromedriver?

javascriptpythongoogle-chromeseleniumselenium-chromedriver

提问by Ryan Weinstein

I've been testing out Selenium with Chromedriver and I noticed that some pages can detect that you're using Selenium even though there's no automation at all. Even when I'm just browsing manually just using chrome through Selenium and Xephyr I often get a page saying that suspicious activity was detected. I've checked my user agent, and my browser fingerprint, and they are all exactly identical to the normal chrome browser.

我一直在用 Chromedriver 测试 Selenium,我注意到一些页面可以检测到您正在使用 Selenium,即使根本没有自动化。即使我只是通过 Selenium 和 Xephyr 使用 chrome 手动浏览,我也经常收到一个页面,说检测到可疑活动。我检查了我的用户代理和我的浏览器指纹,它们都与普通的 Chrome 浏览器完全相同。

When I browse to these sites in normal chrome everything works fine, but the moment I use Selenium I'm detected.

当我用普通的 chrome 浏览这些网站时,一切正常,但是当我使用 Selenium 时,我被检测到了。

In theory chromedriver and chrome should look literally exactly the same to any webserver, but somehow they can detect it.

理论上 chromedriver 和 chrome 对于任何网络服务器来说应该看起来完全一样,但不知何故他们可以检测到它。

If you want some testcode try out this:

如果你想要一些测试代码试试这个:

from pyvirtualdisplay import Display
from selenium import webdriver

display = Display(visible=1, size=(1600, 902))
display.start()
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--disable-extensions')
chrome_options.add_argument('--profile-directory=Default')
chrome_options.add_argument("--incognito")
chrome_options.add_argument("--disable-plugins-discovery");
chrome_options.add_argument("--start-maximized")
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.delete_all_cookies()
driver.set_window_size(800,800)
driver.set_window_position(0,0)
print 'arguments done'
driver.get('http://stubhub.com')

If you browse around stubhub you'll get redirected and 'blocked' within one or two requests. I've been investigating this and I can't figure out how they can tell that a user is using Selenium.

如果您浏览 stubhub,您将在一两个请求内被重定向和“阻止”。我一直在对此进行调查,但我无法弄清楚他们如何判断用户正在使用 Selenium。

How do they do it?

他们是怎么做到的呢?

EDIT UPDATE:

编辑更新:

I installed the Selenium IDE plugin in Firefox and I got banned when I went to stubhub.com in the normal firefox browser with only the additional plugin.

我在 Firefox 中安装了 Selenium IDE 插件,当我在普通的 firefox 浏览器中访问 stubhub.com 时,我被禁止了。

EDIT:

编辑:

When I use Fiddler to view the HTTP requests being sent back and forth I've noticed that the 'fake browser\'s' requests often have 'no-cache' in the response header.

当我使用 Fiddler 查看来回发送的 HTTP 请求时,我注意到“假浏览器”请求的响应标头中通常包含“无缓存”。

EDIT:

编辑:

results like this Is there a way to detect that I'm in a Selenium Webdriver page from Javascriptsuggest that there should be no way to detect when you are using a webdriver. But this evidence suggests otherwise.

像这样的结果有没有办法检测我在来自 Javascript 的 Selenium Webdriver 页面中,建议当您使用 webdriver 时,应该无法检测到。但这个证据表明并非如此。

EDIT:

编辑:

The site uploads a fingerprint to their servers, but I checked and the fingerprint of selenium is identical to the fingerprint when using chrome.

该站点将指纹上传到他们的服务器,但我检查过,硒的指纹与使用 chrome 时的指纹相同。

EDIT:

编辑:

This is one of the fingerprint payloads that they send to their servers

这是他们发送到服务器的指纹有效载荷之一

{"appName":"Netscape","platform":"Linuxx86_64","cookies":1,"syslang":"en-US","userlang":"en-US","cpu":"","productSub":"20030107","setTimeout":1,"setInterval":1,"plugins":{"0":"ChromePDFViewer","1":"ShockwaveFlash","2":"WidevineContentDecryptionModule","3":"NativeClient","4":"ChromePDFViewer"},"mimeTypes":{"0":"application/pdf","1":"ShockwaveFlashapplication/x-shockwave-flash","2":"FutureSplashPlayerapplication/futuresplash","3":"WidevineContentDecryptionModuleapplication/x-ppapi-widevine-cdm","4":"NativeClientExecutableapplication/x-nacl","5":"PortableNativeClientExecutableapplication/x-pnacl","6":"PortableDocumentFormatapplication/x-google-chrome-pdf"},"screen":{"width":1600,"height":900,"colorDepth":24},"fonts":{"0":"monospace","1":"DejaVuSerif","2":"Georgia","3":"DejaVuSans","4":"TrebuchetMS","5":"Verdana","6":"AndaleMono","7":"DejaVuSansMono","8":"LiberationMono","9":"NimbusMonoL","10":"CourierNew","11":"Courier"}}

Its identical in selenium and in chrome

它在硒和铬中相同

EDIT:

编辑:

VPNs work for a single use but get detected after I load the first page. Clearly some javascript is being run to detect Selenium.

VPN 只能使用一次,但在我加载第一页后会被检测到。显然,正在运行一些 javascript 来检测 Selenium。

采纳答案by colossatr0n

For Mac Users

对于 Mac 用户

Replacing cdc_variable using Vim or Perl

cdc_使用 Vim 或 Perl替换变量

You can use vim, or as @Vic Seedoubleyew has pointed out in the answer by @Erti-Chris Eelmaa, perl, to replace the cdc_variable in chromedriver(See post by @Erti-Chris Eelmaa to learn more about that variable). Using vimor perlprevents you from having to recompile source code or use a hex-editor. Make sure to make a copy of the original chromedriverbefore attempting to edit it. Also, the methods below were tested on chromedriver version 2.41.578706.

您可以使用vim,或者正如@Vic Seedoubleyew 在@Erti-Chris Eelmaa 的回答中指出的那样perl,来替换cdc_变量chromedriver请参阅@Erti-Chris Eelmaa 的帖子以了解有关该变量的更多信息)。使用vimperl阻止您重新编译源代码或使用十六进制编辑器。chromedriver在尝试编辑它之前,请确保制作原始副本。此外,以下方法已在chromedriver version 2.41.578706.



Using Vim

使用 Vim

vim /path/to/chromedriver

After running the line above, you'll probably see a bunch of gibberish. Do the following:

运行上面的行后,您可能会看到一堆乱码。请执行下列操作:

  1. Search for cdc_by typing /cdc_and pressing return.
  2. Enable editing by pressing a.
  3. Delete any amount of $cdc_lasutopfhvcZLmcfland replace what was deleted with an equal amount characters. If you don't, chromedriverwill fail.
  4. After you're done editing, press esc.
  5. To save the changes and quit, type :wq!and press return.
  6. If you don't want to save the changes, but you want to quit, type :q!and press return.
  7. You're done.
  1. cdc_通过键入/cdc_并按 进行搜索return
  2. 按 启用编辑a
  3. 删除任意数量的$cdc_lasutopfhvcZLmcfl字符并用等量字符替换已删除的字符。如果你不这样做,chromedriver就会失败。
  4. 完成编辑后,按esc
  5. 要保存更改并退出,请键入:wq!并按return
  6. 如果您不想保存更改,但想退出,请键入:q!并按return
  7. 你完成了。

Go to the altered chromedriverand double click on it. A terminalwindow should open up. If you don't see killedin the output, you successfully altered the driver.

转到已更改chromedriver并双击它。terminal应该打开一个窗口。如果您没有killed在输出中看到,则您已成功更改了驱动程序。



Using Perl

使用 Perl

The line below replaces cdc_with dog_:

下面的行替换cdc_dog_

perl -pi -e 's/cdc_/dog_/g' /path/to/chromedriver

Make sure that the replacement string has the same number of characters as the search string, otherwise the chromedriverwill fail.

确保替换字符串与搜索字符串的字符数相同,否则chromedriver将失败。

Perl Explanation

Perl 解释

s///gdenotes that you want to search for a string and replace it globally with another string (replaces all occurrences).

s///g表示您要搜索一个字符串并用另一个字符串全局替换它(替换所有出现的)。

e.g., s/string/replacment/g

例如, s/string/replacment/g

So,

所以,

s///denotes searching for and replacing a string.

cdc_is the search string.

dog_is the replacement string.

gis the global key, which replaces every occurrence of the string.

s///表示搜索和替换字符串。

cdc_是搜索字符串。

dog_是替换字符串。

g是全局键,它替换字符串的每次出现。

How to check if the Perl replacement worked

如何检查 Perl 替换是否有效

The following line will print every occurrence of the search string cdc_:

以下行将打印每次出现的搜索字符串cdc_

perl -ne 'while(/cdc_/g){print "$&\n";}' /path/to/chromedriver

perl -ne 'while(/cdc_/g){print "$&\n";}' /path/to/chromedriver

If this returns nothing, then cdc_has been replaced.

如果这没有返回任何内容,cdc_则已被替换。

Conversely, you can use the this:

相反,你可以使用这个:

perl -ne 'while(/dog_/g){print "$&\n";}' /path/to/chromedriver

perl -ne 'while(/dog_/g){print "$&\n";}' /path/to/chromedriver

to see if your replacement string, dog_, is now in the chromedriverbinary. If it is, the replacement string will be printed to the console.

查看您的替换字符串 ,dog_现在是否在chromedriver二进制文件中。如果是,则替换字符串将打印到控制台。

Go to the altered chromedriverand double click on it. A terminalwindow should open up. If you don't see killedin the output, you successfully altered the driver.

转到已更改chromedriver并双击它。terminal应该打开一个窗口。如果您没有killed在输出中看到,则您已成功更改了驱动程序。



Wrapping Up

包起来

After altering the chromedriverbinary, make sure that the name of the altered chromedriverbinary is chromedriver, and that the original binary is either moved from its original location or renamed.

更改chromedriver二进制文件后,请确保更改的二进制文件的名称chromedriverchromedriver,并且原始二进制文件已从其原始位置移动或重命名。



My Experience With This Method

我对这种方法的经验

I was previously being detected on a website while trying to log in, but after replacing cdc_with an equal sized string, I was able to log in. Like others have said though, if you've already been detected, you might get blocked for a plethora of other reasons even after using this method. So you may have to try accessing the site that was detecting you using a VPN, different network, or what have you.

我之前在尝试登录时在网站上被检测到,但在替换cdc_为相同大小的字符串后,我能够登录。不过就像其他人所说,如果您已经被检测到,您可能会被阻止即使在使用这种方法之后,还有很多其他原因。因此,您可能必须尝试使用​​ VPN、其他网络或其他网络来访问检测您的站点。

回答by Bassel Samman

It sounds like they are behind a web application firewall. Take a look at modsecurity and owasp to see how those work. In reality, what you are asking is how to do bot detection evasion. That is not what selenium web driver is for. It is for testing your web application not hitting other web applications. It is possible, but basically, you'd have to look at what a WAF looks for in their rule set and specifically avoid it with selenium if you can. Even then, it might still not work because you don't know what WAF they are using. You did the right first step, that is faking the user agent. If that didn't work though, then a WAF is in place and you probably need to get more tricky.

听起来他们在 Web 应用程序防火墙后面。看看 modsecurity 和 owasp 看看它们是如何工作的。实际上,您要问的是如何进行机器人检测规避。这不是 selenium web driver 的用途。它用于测试您的 Web 应用程序而不影响其他 Web 应用程序。这是可能的,但基本上,您必须查看 WAF 在其规则集中查找的内容,并且如果可以的话,特别要避免使用 selenium。即便如此,它可能仍然无法正常工作,因为您不知道他们使用的是什么 WAF。你做了正确的第一步,那就是伪造用户代理。如果这不起作用,那么 WAF 已经到位,您可能需要变得更加棘手。

Edit: Point taken from other answer. Make sure your user agent is actually being set correctly first. Maybe have it hit a local web server or sniff the traffic going out.

编辑:从其他答案中获取的观点。首先确保您的用户代理实际上已正确设置。也许它会访问本地 Web 服务器或嗅探出去的流量。

回答by lfaraone

Even if you are sending all the right data (e.g. Selenium doesn't show up as an extension, you have a reasonable resolution/bit-depth, &c), there are a number of services and tools which profile visitor behaviour to determine whether the actor is a user or an automated system.

即使您发送了所有正确的数据(例如 Selenium 没有显示为扩展,您有合理的分辨率/位深度等),也有许多服务和工具可以分析访问者的行为以确定是否演员是用户或自动化系统。

For example, visiting a site then immediately going to perform some action by moving the mouse directly to the relevant button, in less than a second, is something no user would actually do.

例如,访问一个站点然后立即通过将鼠标直接移动到相关按钮来执行某些操作,在不到一秒钟的时间内,用户实际上不会这样做。

It might also be useful as a debugging tool to use a site such as https://panopticlick.eff.org/to check how unique your browser is; it'll also help you verify whether there are any specific parameters that indicate you're running in Selenium.

作为调试工具,使用https://panopticlick.eff.org/等网站来检查您的浏览器的独特性也可能很有用;它还将帮助您验证是否有任何特定参数表明您正在 Selenium 中运行。

回答by deamentiaemundi

Firefox is said to set window.navigator.webdriver === trueif working with a webdriver. That was according to one of the older specs (e.g.: archive.org) but I couldn't find it in the new oneexcept for some very vague wording in the appendices.

window.navigator.webdriver === true如果使用 webdriver,据说 Firefox 会设置。那是根据较旧的规范之一(例如:archive.org),但除了附录中一些非常模糊的措辞之外,我在规范中找不到它。

A test for it is in the selenium code in the file fingerprint_test.jswhere the comment at the end says "Currently only implemented in firefox" but I wasn't able to identify any code in that direction with some simple greping, neither in the current (41.0.2) Firefox release-tree nor in the Chromium-tree.

对它的测试是在文件指纹测试.js 中的硒代码中,其中末尾的注释说“目前仅在 firefox 中实现”,但我无法通过一些简单的greping识别该方向的任何代码,无论是在当前 (41.0.2) Firefox release-tree 也不在 Chromium-tree 中。

I also found a comment for an older commit regarding fingerprinting in the firefox driver b82512999938 from January 2015. That code is still in the Selenium GIT-master downloaded yesterday at javascript/firefox-driver/extension/content/server.jswith a comment linking to the slightly differently worded appendix in the current w3c webdriver spec.

我还在2015 年 1 月的 firefox 驱动程序b82512999938 中发现了一个关于指纹识别的旧提交的评论。该代码仍在昨天下载的 Selenium GIT-master 中,javascript/firefox-driver/extension/content/server.js其中有一条评论链接到当前 w3c webdriver 规范中措辞略有不同的附录。

回答by PC3TJ

Write an html page with the following code. You will see that in the DOM selenium applies a webdriver attribute in the outerHTML

使用以下代码编写一个 html 页面。你会看到在 DOM selenium 中应用了一个 webdriver 属性在外层HTML

<html>
<head>
  <script type="text/javascript">
  <!--
    function showWindow(){
      javascript:(alert(document.documentElement.outerHTML));
    }
  //-->
  </script>
</head>
<body>
  <form>
    <input type="button" value="Show outerHTML" onclick="showWindow()">
  </form>
</body>
</html>

回答by Kobi K

Try to use selenium with a specific user profile of chrome, That way you can use it as specific user and define any thing you want, When doing so it will run as a 'real' user, look at chrome process with some process explorer and you'll see the difference with the tags.

尝试将 selenium 与 chrome 的特定用户配置文件一起使用,这样您就可以将其用作特定用户并定义您想要的任何内容,这样做时它将作为“真实”用户运行,使用一些进程浏览器查看 chrome 进程和你会看到标签的不同之处。

For example:

例如:

username = os.getenv("USERNAME")
userProfile = "C:\Users\" + username + "\AppData\Local\Google\Chrome\User Data\Default"
options = webdriver.ChromeOptions()
options.add_argument("user-data-dir={}".format(userProfile))
# add here any tag you want.
options.add_experimental_option("excludeSwitches", ["ignore-certificate-errors", "safebrowsing-disable-download-protection", "safebrowsing-disable-auto-update", "disable-client-side-phishing-detection"])
chromedriver = "C:\Python27\chromedriver\chromedriver.exe"
os.environ["webdriver.chrome.driver"] = chromedriver
browser = webdriver.Chrome(executable_path=chromedriver, chrome_options=options)

chrome tag list here

chrome 标签列表在这里

回答by alecxe

As we've already figured out in the question and the posted answers, there is an anti Web-scraping and a Bot detection service called "Distil Networks"in play here. And, according to the company CEO's interview:

正如我们在问题和发布的答案中已经发现的那样,这里有一个反网络抓取和一个名为“Distil Networks”的机器人检测服务。而且,根据公司 CEO 的采访

Even though they can create new bots, we figured out a way to identify Selenium the a tool they're using, so we're blocking Selenium no matter how many times they iterate on that bot. We're doing that now with Python and a lot of different technologies. Once we see a pattern emerge from one type of bot, then we work to reverse engineer the technology they use and identify it as malicious.

尽管他们可以创建新的机器人,但我们找到了一种方法来识别 Selenium 是他们正在使用的工具,因此无论他们在该机器人上迭代多少次,我们都会阻止 Selenium。我们现在正在使用 Python 和许多不同的技术来做到这一点。一旦我们看到一种模式从一种机器人中出现,我们就会对他们使用的技术进行逆向工程,并将其识别为恶意的。

It'll take time and additional challenges to understand how exactly they are detecting Selenium, but what can we say for sure at the moment:

了解他们如何准确检测 Selenium 需要时间和额外的挑战,但目前我们可以肯定地说:

  • it's not related to the actions you take with selenium - once you navigate to the site, you get immediately detected and banned. I've tried to add artificial random delays between actions, take a pause after the page is loaded - nothing helped
  • it's not about browser fingerprint either - tried it in multiple browsers with clean profiles and not, incognito modes - nothing helped
  • since, according to the hint in the interview, this was "reverse engineering", I suspect this is done with some JS code being executed in the browser revealing that this is a browser automated via selenium webdriver
  • 它与您使用 selenium 执行的操作无关 - 一旦您导航到该站点,您就会立即被检测到并被禁止。我试图在动作之间添加人为的随机延迟,在页面加载后暂停 - 没有任何帮助
  • 这也不是关于浏览器指纹 - 在多个浏览器中尝试使用干净的配置文件而不是隐身模式 - 没有任何帮助
  • 因为,根据采访中的提示,这是“逆向工程”,我怀疑这是通过在浏览器中执行一些 JS 代码来完成的,这表明这是一个通过 selenium webdriver 自动化的浏览器

Decided to post it as an answer, since clearly:

决定将其发布为答案,因为很明显:

Can a website detect when you are using selenium with chromedriver?

当您在 chromedriver 中使用 selenium 时,网站可以检测到吗?

Yes.

是的。



Also, what I haven't experimented with is older selenium and older browser versions - in theory, there could be something implemented/added to selenium at a certain point that Distil Networks bot detector currently relies on. Then, if this is the case, we might detect (yeah, let's detect the detector) at what point/version a relevant change was made, look into changelog and changesets and, may be, this could give us more information on where to look and what is it they use to detect a webdriver-powered browser. It's just a theory that needs to be tested.

此外,我还没有尝试过旧的 selenium 和旧的浏览器版本 - 从理论上讲,可能会在某个点实现/添加到 selenium 中,这是 Distil Networks bot 检测器当前依赖的。然后,如果是这种情况,我们可能会检测(是的,让我们检测检测器)在哪个点/哪个版本进行了相关更改,查看变更日志和变更集,并且可能是,这可以为我们提供有关在哪里查看的更多信息他们用什么来检测由 webdriver 驱动的浏览器。这只是一个需要检验的理论。

回答by aianitro

Example of how it's implemented on wellsfargo.com:

它是如何在 wellsfargo.com 上实施的示例:

try {
 if (window.document.documentElement.getAttribute("webdriver")) return !+[]
} catch (IDLMrxxel) {}
try {
 if ("_Selenium_IDE_Recorder" in window) return !+""
} catch (KknKsUayS) {}
try {
 if ("__webdriver_script_fn" in document) return !+""

回答by Erti-Chris Eelmaa

Basically the way the selenium detection works, is that they test for pre-defined javascript variables which appear when running with selenium. The bot detection scripts usually look anything containing word "selenium" / "webdriver" in any of the variables (on window object), and also document variables called $cdc_and $wdc_. Of course, all of this depends on which browser you are on. All the different browsers expose different things.

selenium 检测的工作方式基本上是测试预定义的 javascript 变量,这些变量在使用 selenium 运行时出现。bot 检测脚本通常会在任何变量(在 window 对象上)中查找包含“selenium”/“webdriver”一词的任何内容,并且还会记录名为$cdc_and 的变量$wdc_。当然,所有这些都取决于您使用的是哪种浏览器。所有不同的浏览器都会暴露不同的东西。

For me, I used chrome, so, all that I had todo was to ensure that $cdc_didn't exist anymore as document variable, and voila (download chromedriver source code, modify chromedriver and re-compile $cdc_under different name.)

对我来说,我使用了 chrome,所以,我所要做的就是确保它$cdc_不再作为文档变量存在,瞧(下载 chromedriver 源代码,修改 chromedriver 并$cdc_以不同的名称重新编译。)

this is the function I modified in chromedriver:

这是我在 chromedriver 中修改的功能:

call_function.js:

call_function.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];
}

(note the comment, all I did I turned $cdc_to randomblabla_.

(注意评论,我所做的一切都转向$cdc_randomblabla_.

Here is a pseudo-code which demonstrates some of the techniques that bot networks might use:

这是一个伪代码,它演示了机器人网络可能使用的一些技术:

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;
};

according to user @szx, it is also possible to simply open chromedriver.exe in hex editor, and just do the replacement manually, without actually doing any compiling.

根据用户@szx 的说法,也可以简单地在十六进制编辑器中打开 chromedriver.exe,然后手动进行替换,而无需实际进行任何编译。

回答by bryce

partial interface Navigator { readonly attribute boolean webdriver; };

The webdriver IDL attribute of the Navigator interface must return the value of the webdriver-active flag, which is initially false.

This property allows websites to determine that the user agent is under control by WebDriver, and can be used to help mitigate denial-of-service attacks.

partial interface Navigator { readonly attribute boolean webdriver; };

Navigator 接口的 webdriver IDL 属性必须返回 webdriver-active 标志的值,该值最初为 false。

此属性允许网站确定用户代理受 WebDriver 控制,并可用于帮助减轻拒绝服务攻击。

Taken directly from the 2017 W3C Editor's Draft of WebDriver. This heavily implies that at the very least, future iterations of selenium's drivers will be identifiable to prevent misuse. Ultimately, it's hard to tell without the source code, what exactly causes chrome driver in specific to be detectable.

直接取自2017 W3C Editor's Draft of WebDriver。这在很大程度上意味着,至少,selenium 驱动程序的未来迭代将是可识别的,以防止误用。最终,如果没有源代码,很难说到底是什么导致了特定的 chrome 驱动程序可被检测到。

回答by Néstor

Some sites are detecting this:

一些网站正在检测这个:

function d() {
try {
    if (window.document.$cdc_asdjflasutopfhvcZLmcfl_.cache_)
        return !0
} catch (e) {}

try {
    //if (window.document.documentElement.getAttribute(decodeURIComponent("%77%65%62%64%72%69%76%65%72")))
    if (window.document.documentElement.getAttribute("webdriver"))
        return !0
} catch (e) {}

try {
    //if (decodeURIComponent("%5F%53%65%6C%65%6E%69%75%6D%5F%49%44%45%5F%52%65%63%6F%72%64%65%72") in window)
    if ("_Selenium_IDE_Recorder" in window)
        return !0
} catch (e) {}

try {
    //if (decodeURIComponent("%5F%5F%77%65%62%64%72%69%76%65%72%5F%73%63%72%69%70%74%5F%66%6E") in document)
    if ("__webdriver_script_fn" in document)
        return !0
} catch (e) {}