ChatGPT解决这个技术问题 Extra ChatGPT

当您将 Selenium 与 chromedriver 一起使用时,网站可以检测到吗?

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

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

从理论上讲,chromedriver 和 Chrome 在任何网络服务器上看起来都应该完全一样,但它们可以通过某种方式检测到它。

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

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')

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

他们是怎么做到的呢?

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

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

像这样的结果 Is there a way to detect that I'm in a Selenium Webdriver page from JavaScript 表明应该无法检测到您何时使用网络驱动程序。但这一证据表明并非如此。

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

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

{"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":"WidevineContentDecryptionMo
dule","3":"NativeClient","4":"ChromePDFViewer"},"mimeTypes":
{"0":"application/pdf","1":"ShockwaveFlashapplication/x-shockwave-
flash","2":"FutureSplashPlayerapplication/futuresplash","3":"WidevineContent
DecryptionModuleapplication/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":"Trebu
chetMS","5":"Verdana","6":"AndaleMono","7":"DejaVuSansMono","8":"LiberationM
ono","9":"NimbusMonoL","10":"CourierNew","11":"Courier"}}

它在 Selenium 和 Chrome 中是相同的。

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

@RyanWeinstein:这不是流量。我的猜测是 Selenium 需要公开一些可以在客户端 JavaScript 上检测到的 JavaScript 钩子。
或者如果它是流量,那么它就是一种流量模式......你浏览页面的速度太快了。
我没有浏览太快。我只加载一个页面,并使用鼠标和键盘正常浏览它。 Selenium 需要暴露钩子也没有任何意义,因为它实际上是在运行 chrome.exe。它只是运行普通的 chrome 并允许您从中获取数据。还有其他想法吗?我在想也许它与饼干有关。这真让我抓狂。
此站点使用 distill 机器人检测技术并使用来自不同 IP 的 akamaitechnologies.com CDN 提供内容,例如 95.100.59.245104.70.243.6623.202.161.241
我在使用 Selenium 和 firefox 驱动程序时遇到了同样的问题。值得注意的是,我在通过 NAT 访问 Internet 的 VMWare 工作站虚拟机中运行 Selenium。宿主机可以访问 stubhub,而 VM 在使用 Selenium 时无法访问,甚至浏览器实例 Selenium 启动时也无法访问。我已经阻止了 VM 浏览器实例,并且 stubhub 仍然可以识别机器并将其阻止。所以它必须以某种方式执行浏览器和机器的指纹。

P
Peter Mortensen

基本上,Selenium 检测的工作方式是,它们测试使用 Selenium 运行时出现的预定义 JavaScript 变量。 bot 检测脚本通常会在任何变量(在窗口对象上)中查找包含单词“selenium”/“webdriver”的任何内容,以及称为 $cdc_$wdc_ 的文档变量。当然,所有这些都取决于您使用的浏览器。所有不同的浏览器都暴露了不同的东西。

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

这是我在chromedriver中修改的函数:

文件 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];
}

(注意评论。我所做的一切都是将 $cdc_ 变成 randomblabla_。)

以下是演示僵尸网络可能使用的一些技术的伪代码:

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,也可以在十六进制编辑器中简单地打开 chromedriver.exe,然后手动进行替换,而无需实际进行任何编译。


是的,它在没有问题的情况下工作,请注意一个问题是,如果您在此更改之前落入“黑名单”,则很难摆脱。如果你想摆脱现有的黑名单,你需要实现fake canvas指纹,禁用flash,改变IP,改变请求头顺序(交换语言和接受头)。一旦你落入黑名单,他们有很好的措施来跟踪你,即使你改变了 IP,即使你在隐身模式下打开 chrome 等等
我只是在十六进制编辑器中用 chromedriver.exe 中的 xxxx 替换了 $cdc,它就成功了!我还注意到,如果您最大化浏览器窗口(而不是使用预定义的大小),它的检测频率就会降低。
这是在windows、osx还是linux上? osx 上的十六进制编辑似乎不起作用。
用 $zzz_zzzzzzzzzzzzzzzzzzzzzz_ (相同数量的字符)进行十六进制编辑但没有用。
@Erti-ChrisEelmaa 您是否知道任何无法检测到的开源分支?
c
colossatr0n

替换 cdc_ 字符串

您可以使用 vimperl 替换 chromedriver 中的 cdc_ 字符串。 请参阅 answer by @Erti-Chris Eelmaa 以了解有关该字符串以及它如何成为检测点的更多信息

使用 vimperl 可以避免重新编译源代码或使用十六进制编辑器。

确保在尝试编辑之前复制原始 chromedriver

我们的目标是更改类似于 $cdc_lasutopfhvcZLmcflcdc_ 字符串。

以下方法在 chromedriver version 2.41.578706 上进行了测试。

使用 Vim

vim /path/to/chromedriver

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

通过键入 :%s/cdc_/dog_/g 将所有 cdc_ 实例替换为 dog_。 dog_ 只是一个例子。您可以选择任何内容,只要它具有与搜索字符串相同数量的字符(例如,cdc_),否则 chromedriver 将失败。要保存更改并退出,请输入 :wq!然后按回车。如果您需要退出而不保存更改,请输入 :q!然后按回车。

使用 Perl

下面的行将所有出现的 cdc_ 替换为 dog_。归功于 Vic Seedoubleyew

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

确保替换字符串(例如,dog_)与搜索字符串(例如,cdc_)的字符数相同,否则 chromedriver 将失败。

包起来

要验证是否替换了所有出现的 cdc_

grep "cdc_" /path/to/chromedriver

如果没有返回输出,则替换成功。

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

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

我对这种方法的体验

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


@LekaBaper 感谢您的提醒。我使用的 chromedriver 版本是 2.41.578706。
即使我在不同网络上的新物理计算机上使用此 chromedriver.exe 修改,也无法正常工作。
它给出一个错误说,这个版本不能在这台电脑上工作:(
请注意,chromedriver 人员已声明此问题无法修复,因此您可以预期必须使用 fork 或无限期地编辑二进制文件。 bugs.chromium.org/p/chromedriver/issues/detail?id=3220
TLDR;在十六进制编辑器中打开二进制文件,将以 $cdc 开头的字符串更改为其他相同长度的字符串,然后保存并运行修改后的二进制文件。
a
alecxe

正如我们已经在问题和发布的答案中发现的那样,这里有一个名为 "Distil Networks" 的反 Web 抓取和 Bot 检测服务。而且,根据公司 CEO 的interview

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

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

它与您使用 selenium 执行的操作无关 - 一旦您导航到该站点,您就会立即被检测到并被禁止。我试图在动作之间添加人为的随机延迟,在页面加载后暂停 - 没有任何帮助

这也与浏览器指纹无关-在具有干净配置文件而不是隐身模式的多个浏览器中尝试过-没有任何帮助

因为,根据采访中的提示,这是“逆向工程”,我怀疑这是通过在浏览器中执行的一些 JS 代码完成的,这表明这是一个通过 selenium webdriver 自动化的浏览器

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

网站可以检测到您何时将硒与 chromedriver 一起使用?

是的。

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


@RyanWeinstein 好吧,我们没有实际证据,我们只能推测和测试。现在,我想说他们有办法使用硒来检测我们。尝试使用 selenium 版本 - 这可能会给你一些线索。
这可能与如何确定临时端口有关吗?该方法远离众所周知的范围。 github.com/SeleniumHQ/selenium/blob/…
Easyjet 正在使用 distilnetwork 服务,是的,它可以阻止虚拟机器人,但不能阻止复杂的机器人,因为我们已经测试了它每天有超过 2000 个来自不同 IP 的请求(我们再次使用“相同”地址)所以基本上每个 IP 都适用每天有 5-10 个请求,由此我可以看出,所有这些机器人检测服务只是为了开发和销售大约 45% 的工作算法,我们使用的抓取工具很容易检测到我可以阻止它,而 destilnetworks、squareshield 和其他不能,这促使我永远不要使用它们中的任何一个。
我认为他们在 chrome webdriver 中检测到 navigator.webdriver。我试图在 intoli.com/blog/not-possible-to-block-chrome-headlessstackoverflow.com/questions/47297877/… 的帮助下使 navigator.webdriver = false。它返回一个机器人检测页面而不是 distilnetworks.com/distil_identify_cookie.html
u
undetected Selenium

关于检测到由 Selenium 控制的 ChromeDriver 驱动的网站,已经进行了很多分析和讨论。这是我的两分钱:

根据文章 Browser detection using the user agent,为不同的浏览器提供不同的网页或服务通常不是最好的想法。网络意味着每个人都可以访问,无论用户使用哪种浏览器或设备。概述了开发网站的最佳实践,以根据功能可用性而不是针对特定浏览器来逐步增强自身。

但是,浏览器和标准并不完美,仍然存在一些边缘情况,即某些网站仍然会检测到浏览器,并且如果浏览器是由 Selenium 控制的 WebDriver 驱动的。可以通过不同的方式检测浏览器,一些常用的机制如下:

实施验证码/重新验证码以检测自动机器人。

您可以在 Recaptcha 3 如何知道我正在使用 selenium/chromedriver 中找到相关的详细讨论?

在无头 Chrome UserAgent 中检测术语 HeadlessChrome

您可以在 Linux 上使用无头 Chrome 的访问被拒绝页面中找到相关的详细讨论,而有头 Chrome 通过 Python 使用 Selenium 在 Windows 上工作

使用 Distil Networks 的 Bot Management 服务

您可以在无法使用 Selenium 自动登录 Chase 站点中找到相关的详细讨论

使用 Akamai 的 Bot Manager 服务

当使用 Selenium 和 Python 传递值时,您可以在 https://www.nseindia.com/ 上的动态下拉列表中找到相关的详细讨论

使用 Datadome 的 Bot Protection 服务

您可以在使用 Selenium 和 Python 抓取时使用 DataDome 获取验证码被阻止的网站中找到相关的详细讨论

但是,使用 检测浏览器看起来很简单,但要做好实际上有点困难。

注意:此时值得一提的是:使用用户代理嗅探几乎不是一个好主意。总是有更好和更广泛兼容的方法来解决某个问题。

浏览器检测的注意事项

检测浏览器背后的想法可以是以下任何一种:

试图解决某些特定变体或特定版本的网络浏览器中的特定错误。

尝试检查某些浏览器尚不支持的特定功能是否存在。

尝试根据所使用的浏览器提供不同的 HTML。

通过 UserAgents 替代浏览器检测

浏览器检测的一些替代方案如下:

实施测试以检测浏览器如何实现功能的 API 并从中确定如何使用它。一个例子是 Chrome 在正则表达式中未标记的实验性后向支持。

采用渐进式增强的设计技术,这将涉及分层开发网站,使用自下而上的方法,从更简单的层开始,并在连续层中提高网站的功能,每个层都使用更多功能。

采用自上而下的优雅降级方法,我们使用我们想要的所有功能构建尽可能好的网站,然后对其进行调整以使其在旧版浏览器上工作。

解决方案

为了防止检测到 Selenium 驱动的 WebDriver,一个小众方法将包括以下提到的方法之一/所有:

在每次执行测试套件时使用 fake_useragent 模块轮换 UserAgent,如下所示: from selenium import webdriver from selenium.webdriver.chrome.options import Options from fake_useragent import UserAgent options = Options() ua = UserAgent() userAgent = ua.random print (userAgent) options.add_argument(f'user-agent={userAgent}') driver = webdriver.Chrome(chrome_options=options, executable_path=r'C:\WebDrivers\ChromeDriver\chromedriver_win32\chromedriver.exe') driver.get( "https://www.google.co.in") driver.quit()

您可以在如何在 Selenium 中更改 Google Chrome 用户代理中找到相关的详细讨论?

使用 Network.setUserAgentOverride 通过 execute_cdp_cmd() 在每个测试中旋转 UserAgent,如下所示: from selenium import webdriver driver = webdriver.Chrome(executable_path=r'C:\WebDrivers\chromedriver.exe') print(driver.execute_script(" return navigator.userAgent;")) # 将用户代理设置为 Chrome/83.0.4103.97 driver.execute_cdp_cmd('Network.setUserAgentOverride', {"userAgent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ( KHTML,如 Gecko) Chrome/83.0.4103.97 Safari/537.36'}) print(driver.execute_script("return navigator.userAgent;"))

您可以在如何使用 Selenium 和 Python 更改用户代理中找到相关的详细讨论

将 webdriver 的 navigator 的属性值更改为 undefined 如下: driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", { "source": """ Object.defineProperty(navigator, 'webdriver', { get: () => undefined } ) """ })

您可以在 Selenium webdriver 中找到相关的详细讨论:修改 navigator.webdriver flag to prevent selenium detection

更改 navigator.plugins、navigator.languages、WebGL、细线特征、缺失图像等的值。

您可以在 Is there a version of selenium webdriver that is not detected? 中找到相关的详细讨论?

更改常规视口

您可以在 How to bypass Google captcha with Selenium and python 中找到相关的详细讨论?

处理 reCAPTCHA

在处理 而不是点击与文本相关的 我不是机器人 时,提取和使用 data-sitekey 可能更容易获得认证。

您可以在如何识别 ReCaptcha V2 的 32 位数据站点密钥以使用 Selenium 和 Python 请求以编程方式获取有效响应中找到相关的详细讨论?

tl;博士

您可以在以下位置找到逃避 webdriver 检测的尖端解决方案:

selenium-stealth - 一种经过验证的逃避 webdriver 检测的方法


我在bloomberg.com 上测试了你的python 代码。仍然认我是机器人。
将 webdriver 的 navigator 的属性值更改为 undefined 对我有用!
S
Shubham Jain

在 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 !+""

为什么最后一次尝试没有关闭?除了你能解释一下你的答案吗?
S
ShayanKM

混淆 JavaScript 结果

我已经检查了 chromedriver 源代码。这会向浏览器注入一些 javascript 文件。
此链接上的每个 javascript 文件都会注入网页: https://chromium.googlesource.com/chromium/src/+/master/chrome/test/chromedriver/js/

所以我使用逆向工程并通过十六进制编辑混淆了js文件。现在我确信不再使用 javascript 变量、函数名和固定字符串来发现 selenium 活动。但仍有一些网站和 reCaptcha 检测到硒!也许他们检查了由 chromedriver js 执行引起的修改:)

编辑1:

Chrome 'navigator' 参数修改

我发现“导航器”中有一些参数可以简要介绍 chromedriver 的使用。这些是参数:

“navigator.webdriver” 在非自动模式下它是“未定义的”。在自动模式下,它是“真实的”。

“navigator.plugins”在无头镀铬上的长度为 0。所以我添加了一些虚假的元素来欺骗插件长度检查过程。

"navigator.languages" 设置为默认 chrome 值 '["en-US", "en", "es"]' 。

所以我需要的是一个 chrome 扩展来在网页上运行 javascript。我使用文章中提供的 js code 做了一个扩展,并使用 another article 将压缩后的扩展添加到我的项目中。 我已成功更改值;但仍然没有任何改变!

我没有找到像这样的其他变量,但这并不意味着它们不存在。 reCaptcha 还是检测到 chromedriver,所以应该有更多的变量需要改变。下一步应该是我不想做的检测器服务的逆向工程。

现在我不确定是否值得花更多时间在这个自动化过程上或寻找替代方法!


这是否可能通过十六进制编辑器删除 $cdc 条目?
K
Kobi K

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

例如:

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 标签列表 here


u
undetected Selenium

随着 Selenium Stealth 的出现,避免检测由 Selenium 驱动的 ChromeDriver 发起的 浏览上下文 变得更加容易。

硒隐形

selenium-stealth 是一个防止检测的 python 包。这个程序试图让 python selenium 更加隐蔽。但是,目前 selenium-stealth 仅支持 Selenium Chrome。

目前 selenium-stealth 可以提供的功能:

selenium-stealth 隐身通过了所有公共机器人测试。

使用 selenium-stealth selenium 可以做 google 帐户登录。

selenium-stealth 有助于维持正常的 reCAPTCHA v3 分数

安装

Selenium-stealth 在 PyPI 上可用,因此您可以使用 pip 安装,如下所示:

$ pip install selenium-stealth

selenium4 兼容代码

代码块: from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.chrome.service import Service from selenium_stealth import Stealth options = Options() options.add_argument("start-maximized") # Chrome 被控制通过自动化测试软件 options.add_experimental_option("excludeSwitches", ["enable-automation"]) options.add_experimental_option('useAutomationExtension', False) s = Service('C:\\BrowserDrivers\\chromedriver.exe') driver = webdriver .Chrome(service=s, options=options) # Selenium Stealth 设置隐形(驱动程序,languages=["en-US", "en"], vendor="Google Inc.", platform="Win32", webgl_vendor=" Intel Inc.", renderer="Intel Iris OpenGL Engine", fix_hairline=True, ) driver.get("https://bot.sannysoft.com/")

浏览器截图:

https://i.stack.imgur.com/ZxqMB.png

tl;博士

您可以在以下位置找到一些相关的详细讨论:

当您将 Selenium 与 chromedriver 一起使用时,网站可以检测到吗?

如何自动登录到正在检测我使用 selenium-stealth 登录尝试的站点

未检测到的 Chromedriver 未正确加载


b
bryce

部分接口 Navigator { 只读属性 boolean webdriver; }; Navigator 接口的 webdriver IDL 属性必须返回 webdriver-active 标志的值,该标志最初为 false。此属性允许网站确定用户代理受 WebDriver 控制,并可用于帮助缓解拒绝服务攻击。

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


“没有源代码很难说”..源代码是免费提供的
我的意思是没有相关网站的源代码。很难说他们在检查什么。
d
deamentiaemundi

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

对它的测试是在文件 fingerprint_test.js 中的 selenium 代码中,其中最后的注释说“当前仅在 firefox 中实现”,但我无法通过一些简单的 grep 识别该方向的任何代码,在当前 (41.0.2) Firefox 发布树和 Chromium-tree 中都没有。

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


我刚刚用 Firefox 55 测试了 webdriver,我可以确认这不是真的。变量 window.navigator.webdriver 未定义。
更新:我用 Firefox 65 进行了测试,这是真的:window.navigator.webdriver == true
P
Peter Mortensen

除了 the great answer of Erti-Chris Eelmaa - 还有令人讨厌的 window.navigator.webdriver,它是只读的。如果您将其值更改为 false,则事件仍将具有 true。这就是为什么仍然可以检测到由自动化软件驱动的浏览器。

MDN

该变量由 chrome 中的标志 --enable-automation 管理。 chromedriver 使用该标志启动 Chrome,Chrome 将 window.navigator.webdriver 设置为 true。您可以找到它here。您需要将标志添加到“排除开关”。例如 (Go):

package main

import (
    "github.com/tebeka/selenium"
    "github.com/tebeka/selenium/chrome"
)

func main() {

caps := selenium.Capabilities{
    "browserName": "chrome",
}

chromeCaps := chrome.Capabilities{
    Path:            "/path/to/chrome-binary",
    ExcludeSwitches: []string{"enable-automation"},
}
caps.AddChrome(chromeCaps)

wd, err := selenium.NewRemote(caps, fmt.Sprintf("http://localhost:%d/wd/hub", 4444))
}

U
Usman Gani

它适用于某些网站,从导航器中删除属性 webdriver

from selenium import webdriver
driver = webdriver.Chrome()
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
    "source":
        "const newProto = navigator.__proto__;"
        "delete newProto.webdriver;"
        "navigator.__proto__ = newProto;"
    })

S
Shubham Jain

我发现的另一件事是某些网站使用检查用户代理的平台。如果该值包含:“HeadlessChrome”,则使用无头模式时行为可能会很奇怪。

解决方法是覆盖用户代理值,例如在 Java 中:

chromeOptions.addArguments("--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36");

s
svinec

我所要做的就是:

my_options = webdriver.ChromeOptions()
my_options.add_argument( '--disable-blink-features=AutomationControlled' )

更多信息:这与网站 skyscanner.com 有关。在过去,我已经能够刮掉它。是的,它确实检测到了浏览器自动化,它给了我一个验证码来按住一个按钮。我以前可以手动完成验证码,然后搜索航班,然后抓取。但是这一次在完成验证码后,我一次又一次地得到相同的验证码,似乎无法摆脱它。我尝试了一些最流行的建议来避免检测到自动化,但它们没有奏效。然后我发现 this article 确实有效,通过消除过程我发现它只需要上面的选项来绕过他们的浏览器自动化检测。现在我什至没有得到验证码,其他一切似乎都正常工作。

我目前正在运行的版本:

操作系统:Windows 7 64 位

Python 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:37:50) [MSC v.1916 64 bit (AMD64)] on win32

浏览器:Chrome 版本 100.0.4896.60(官方版本)(64 位)

硒 4.1.3

ChromeDriver 100.0.4896.60 chromedriver_win32.zip 930ff33ae8babeaa74e0dd1ce1dae7ff


M
M3RS

我看到的机器人检测似乎比我在下面的答案中读到的更复杂或至少不同。

实验一:

我从 Python 控制台使用 Selenium 打开浏览器和网页。鼠标已经位于我知道页面加载后将出现链接的特定位置。我从不移动鼠标。我按下鼠标左键一次(这是从运行 Python 的控制台到浏览器的焦点)。我再次按下鼠标左键(请记住,光标位于给定链接上方)。该链接应正常打开。

实验 2:

和以前一样,我从 Python 控制台打开浏览器和带有 Selenium 的网页。这一次,我没有使用鼠标单击,而是使用 Selenium(在 Python 控制台中)单击具有随机偏移量的相同元素。链接打不开,但我被带到了一个注册页面。

影响:

通过 Selenium 打开网络浏览器并不妨碍我成为人类

像人类一样移动鼠标不一定被归类为人类

通过 Selenium 点击带有偏移量的东西仍然会引发警报

看起来很神秘,但我想他们可以确定一个动作是否来自 Selenium,而他们并不关心浏览器本身是否是通过 Selenium 打开的。或者他们可以确定窗口是否有焦点?如果有人有任何见解会很有趣。


我的信念是 Selenium 通过 javascript 在页面中注入一些东西来查找和访问元素。我相信他们正在检测这种注射。
你是对的,这个测试是 100% 有效的。我做了类似的测试,结果相同。我可以发送 Enter 选项卡或发送密钥。在我访问元素的那一刻,页面停止工作。因此,如果驱动程序将一些 javascript 注入浏览器。我们可以使用 chrome 扩展名加密该 javascript,并使用相同的扩展名在下一页解密。我会在接下来的几天里试着看看它。
你能提供一个链接来测试这种行为吗?我想研究这种检测方法并创建一个旁路
我很想看看你是否可以在无头 chrome 中绕过它,因为这里支持扩展
它不是那样工作的。网站可以使用多种服务和方法来检测机器人。最好的方法是通过指纹检测硒。但还有很多其他的。
P
Peter Mortensen

听起来他们在 Web 应用程序防火墙后面。查看 modsecurity 和 OWASP 以了解它们是如何工作的。

实际上,您要问的是如何进行机器人检测规避。这不是 Selenium WebDriver 的用途。它用于测试您的 Web 应用程序而不影响其他 Web 应用程序。这是可能的,但基本上,您必须查看 WAF 在其规则集中查找的内容,并在可能的情况下特别避免使用 selenium。即使那样,它可能仍然无法正常工作,因为您不知道他们使用的是什么 WAF。

您做了正确的第一步,即伪造用户代理。如果这不起作用,那么 WAF 已经到位,您可能需要变得更加棘手。

观点取自其他答案。首先确保您的用户代理实际上设置正确。也许让它访问本地网络服务器或嗅探流出的流量。


我认为你在正确的道路上。我用我的设置进行了测试,并将用户代理替换为成功通过并收到相同结果的有效用户代理字符串,stubhub 阻止了请求。
这个话题非常广泛,如果你不理解它,我会说,如果你想理解它,这里不是正确的地方。从 owasp 开始。研究渗透测试和网络安全。另外,就像我之前说的,专门针对这个主题研究 modsecurity 和 WAF。
如果是 HTTP 标头问题,那么普通浏览器不会被阻止吗? HTTP 标头完全相同。另外我到底在用那个 github 链接看什么?您是否尝试过使用 selenium 进行 stubhub?有些东西很不对劲。
我很抱歉造成混乱。我会调查的,如果你不想的话,你不必再帮助我了。我的大部分经验是在编程系统应用程序中,所以我不熟悉你所说的这些 modsecurity 规则。我会看看并尝试教育自己。我没有试图绕过任何东西,我只是想知道这些网站如何检测使用 selenium 的用户。
我也是开发人员:)。学习是我可以落后的原因。我不介意提供帮助,我只是想明确表示我不知道您的意图,也无法完全帮助您绕过他们的网站安全。不过,要回答您的问题,他们检测的不是硒。这些规则检测到可疑行为,并决定对违规客户采取适当措施。他们通过你没有做的事情而不是你正在做的事情来抓住你。在 repo 链接中,您可以签出此文件以了解 base_rules/modsecurity_crs_20_protocol_violations.conf
l
lfaraone

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

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

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


我已经使用过该网站,指纹与我的普通浏览器相同。我也没有自动化任何东西。我只是正常浏览。
N
Néstor

一些网站正在检测到这一点:

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) {}

这不适用于 Chrome 和 Firefox、selenium 3.5.0、ChromeDriver 2.31.488774、geckodriver 0.18.0
p
pguardiario

在我看来,使用 Selenium 最简单的方法是拦截发送回浏览器指纹的 XHR。

但由于这是一个仅限 Selenium 的问题,所以最好只使用其他东西。 Selenium 应该让这样的事情变得更容易,而不是更难。


硒还有哪些其他选择?
我猜 Requests 将是主要的 python 选项。如果您发送的请求与您的浏览器发送的完全相同,您将显示为普通浏览器。
实际上,如果目标网站对您需要访问/执行的某些操作使用 javascript,则您必须使用 selenium。否则,您应该使用请求,因为它要快得多。我认为问题是找到一些其他类似于 selenium 的 chromedriver/解决方案。我听说过phantomJS,我会试试的。
@V-cash - 这些天我推荐 python playwright,欺骗请求变得越来越难。
@pguardiario - 你的意思是你只使用 python,没有 requests 模块?如果这是正确的,你怎么做?
P
PC3TJ

使用以下代码编写一个 html 页面。您将看到在 DOM 中 selenium 在 outerHTML 中应用了 webdriver 属性

< /html>


该属性仅在 Firefox 中添加。
并且可以从控制浏览器的 selenium 扩展中删除它。无论如何它都会起作用。
S
Serhii Matvienko

您可以尝试使用参数“启用自动化”

var options = new ChromeOptions();

// hide selenium
options.AddExcludedArguments(new List<string>() { "enable-automation" });

var driver = new ChromeDriver(ChromeDriverService.CreateDefaultService(), options);

但是,我想提醒您,此功能已在 ChromeDriver 79.0.3945.16 中修复。所以可能你应该使用旧版本的 chrome。

此外,作为另一种选择,您可以尝试使用 InternetExplorerDriver 而不是 Chrome。至于我,IE 根本不会阻止,没有任何黑客攻击。

有关更多信息,请尝试查看此处:

Selenium webdriver: Modifying navigator.webdriver flag to prevent selenium detection

Unable to hide "Chrome is being controlled by automated software" infobar within Chrome v76


D
Dharman

答案:是的

有些网站会通过浏览器的指纹和其他数据检测硒,其他网站会根据行为检测硒,不仅基于你做了什么,还基于你没有做什么。

通常使用 selenium 提供的数据就足以检测到它。

您可以在此类网站中检查浏览器指纹

https://bot.sannysoft.com
https://fingerprintjs.github.io/fingerprintjs/
https://antoinevastel.com/bots/

尝试使用您的用户浏览器,然后尝试使用 selenium,您会看到差异。

您可以使用 options() 更改一些指纹,例如用户代理等,您自己查看结果。

您可以尝试通过多种方式避免这种检测,我建议使用这个库:undetected_chromedriver:

https://github.com/ultrafunkamsterdam/undetected-chromedriver

import undetected_chromedriver.v2 as uc

否则,您可以尝试使用硒的替代品。我听说过 PhantomJS,但没有尝试过。


如果您查看代码,您会发现他自动实现了此线程中涵盖的所有方面,包括十六进制编辑 chromedriver。
我认为他没有尝试无法检测到的 chromedriver 或使用硒的替代品。我最近学到的另一件事,我不知道我是否完全理解,但似乎 selenium 实际上不会产生点击,它“模拟”它们发出 HTTP 请求。这是检测硒的好方法,因为人类会进行真正的点击
这实际上很有趣 - 也许最好使用 javascript 执行来“点击”?沿着同一个线程,我在一个站点上特别注意到,如果我使用 driver.refresh(),我会立即被标记。可能与您描述的机制相同?
在这种情况下,我不确定为什么会这样,但您可以将 cookie 保存到 pickle 文件中,然后再次加载 cookie,然后再加载 driver.get(url),而不是使用 driver.refresh()。如果您对如何加载 cookie 有疑问,请查看此链接:https://stackoverflow.com/questions/15058462/how-to-save-and-load-cookies-using-python-selenium-webdriver
P
Peter Mortensen

我发现像这样更改 JavaScript“key”变量:

//Fools the website into believing a human is navigating it
((JavascriptExecutor)driver).executeScript("window.key = \"blahblah\";");

在将 Selenium WebDriver 与 Google Chrome 一起使用时适用于某些网站,因为许多网站会检查此变量以避免被 Selenium 抓取。


H
Herahadi An

我有同样的问题,并通过以下配置解决了这个问题(在 c# 中)

options.AddArguments("start-maximized");
                options.AddArguments("--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36");

                options.AddExcludedArgument("enable-automation");//for hiding chrome being controlled by automation..
                options.AddAdditionalCapability("useAutomationExtension", false);

//import cookies
options.AddArguments("user-data-dir=" + userDataDir);

                options.AddArguments("profile-directory=" + profileDir);