【问题标题】:Can a website detect when you are using Selenium with chromedriver?当您将 Selenium 与 chromedriver 一起使用时,网站可以检测到吗?
【发布时间】:2019-05-22 02:02:15
【问题描述】:

我一直在用 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 bot 检测技术,并使用akamaitechnologies.com CDN 从不同的ips 提供内容,例如95.100.59.245104.70.243.6623.202.161.241
  • 我在使用 Selenium 和 firefox 驱动程序时遇到了同样的问题。值得注意的是,我在通过 NAT 访问 Internet 的 VMWare 工作站虚拟机中运行 Selenium。宿主机可以访问 stubhub,而 VM 在使用 Selenium 时无法访问,甚至浏览器实例 Selenium 启动时也无法访问。我已经阻止了 VM 浏览器实例,并且 stubhub 仍然可以识别机器并将其阻止。所以它必须以某种方式执行浏览器和机器的指纹。

标签: javascript python google-chrome selenium selenium-chromedriver


【解决方案1】:

随着Selenium Stealth 的可用性,逃避检测Selenium 驱动ChromeDriver 发起 浏览上下文变得更加容易。


硒隐身

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

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

  • selenium-stealth 通过所有公共机器人测试。

  • 用selenium-stealth selenium 可以做google账号登录。

  • 硒隐形有助于维持正常的 reCAPTCHA v3 分数


安装

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

$ pip install selenium-stealth

兼容代码

  • 代码块:

    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 is controlled by automated test software
    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 settings
    stealth(driver,
          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/")
    
  • 浏览器截图:


tl;博士

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

【讨论】:

    【解决方案2】:

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

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

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

    您可以在How does recaptcha 3 know I'm using selenium/chromedriver?找到相关的详细讨论

    • headless Chrome UserAgent 中检测到术语 HeadlessChrome

    您可以在Access Denied page with headless Chrome on Linux while headed Chrome works on windows using Selenium through Python找到相关的详细讨论

    您可以在Unable to use Selenium to automate Chase site login找到相关的详细讨论

    • 使用来自AkamaiBot Manager服务

    您可以在Dynamic dropdown doesn't populate with auto suggestions on https://www.nseindia.com/ when values are passed using Selenium and Python找到相关的详细讨论

    • 使用来自DatadomeBot Protection 服务

    您可以在Website using DataDome gets captcha blocked while scraping using Selenium and Python找到相关的详细讨论

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

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


    浏览器检测的注意事项

    检测浏览器背后的思路可以是以下两种:

    • 尝试解决某些特定变体或特定版本的网络浏览器中的特定错误。
    • 尝试检查是否存在某些浏览器尚不支持的特定功能。
    • 尝试根据所使用的浏览器提供不同的 HTML。

    通过 UserAgents 检测浏览器的替代方法

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

    • 实施测试以检测浏览器如何实施功能的 API 并从中确定如何使用它。一个例子是Chrome unflagged experimental lookbehind support in regular expressions
    • 适应渐进增强的设计技术,这将涉及在中开发网站,使用自下而上的方法,从更简单的层开始并提高网站在连续的层中,每层都使用更多的功能。
    • 采用自上而下的优雅降级方法,在这种方法中,我们使用我们想要的所有功能构建尽可能好的网站,然后对其进行调整以使其适用于旧版浏览器。

    解决方案

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

    • 使用 fake_useragent 模块在每次执行 Test Suite 时轮换 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()
      

    您可以在Way to change Google Chrome user agent in Selenium?找到相关的详细讨论

    • 使用Network.setUserAgentOverrideexecute_cdp_cmd() 在您的每个测试 中旋转UserAgent,如下所示:

      from selenium import webdriver
      
      driver = webdriver.Chrome(executable_path=r'C:\WebDrivers\chromedriver.exe')
      print(driver.execute_script("return navigator.userAgent;"))
      # Setting user agent as 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, like Gecko) Chrome/83.0.4103.97 Safari/537.36'})
      print(driver.execute_script("return navigator.userAgent;"))
      

    您可以在How to change the User Agent using Selenium and Python找到相关的详细讨论

    • 将 webdriver 的 navigatorproperty 值更改为 undefined,如下所示:

      driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
        "source": """
          Object.defineProperty(navigator, 'webdriver', {
            get: () => undefined
          })
        """
      })
      

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

    • 更改navigator.pluginsnavigator.languagesWebGL细线特征的值>缺少图片

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

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


    处理 reCAPTCHA

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

    您可以在How to identify the 32 bit data-sitekey of ReCaptcha V2 to obtain a valid response programmatically using Selenium and Python Requests?找到相关的详细讨论


    tl;博士

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

    【讨论】:

    • 我在bloomberg.com 上测试了你的python 代码。仍然认我是机器人。
    【解决方案3】:

    我有同样的问题,并通过以下配置解决了这个问题(在 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);
    

    【讨论】:

      【解决方案4】:

      答案:是的

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

      通常使用 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
      【解决方案5】:

      它适用于某些网站,从导航器中删除属性 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;"
          })
      

      【讨论】:

      • 应用 @colossatr0n 的答案并不能解决问题,我在 colossatr0n 之后应用了你的答案。现在可以了!
      • 祝你好运@MehmetBurakSayıcı
      • 有帮助,但不是对每个网站都有用
      【解决方案6】:

      替换cdc_字符串

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

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

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

      我们的目标是更改cdc_ 字符串,它看起来类似于$cdc_lasutopfhvcZLmcfl

      以下方法已在 chromedriver version 2.41.578706 上测试。


      使用 Vim

      vim /path/to/chromedriver
      

      运行上述代码后,您可能会看到一堆乱码。执行以下操作:

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

      使用 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开头的字符串更改为其他相同长度的字符串,然后保存并运行修改后的二进制文件。
      【解决方案7】:

      除了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))
      }
      

      【讨论】:

        【解决方案8】:

        基本上,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 等等
        • 我找到了文件“/Users/your_username/chromium/src/chrome/test/chromedriver/js”
        • 我只是在十六进制编辑器中将$cdc 替换为chromedriver.exe 中的xxxx,它就成功了!我还注意到,如果您最大化浏览器窗口(而不是使用预定义的大小),则检测频率会降低。
        • 这是在 windows、osx 还是 linux 上? osx 上的十六进制编辑似乎不起作用。
        • 用 $zzz_zzzzzzzzzzzzzzzzzzzzzz_ 进行十六进制编辑(相同数量的字符),但没有用。
        【解决方案9】:

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

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

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

        【讨论】:

          【解决方案10】:

          听起来他们在 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
          【解决方案11】:

          你可以尝试使用参数“enable-automation”

          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

          【讨论】:

            【解决方案12】:

            我发现的另一件事是,一些网站使用检查用户代理的平台。如果该值包含:“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");
            

            【讨论】:

              【解决方案13】:

              混淆 JavaScripts 结果

              我已经检查了 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" 在无头 chrome 上的长度为 0。所以我添加了一些虚假的元素来欺骗插件长度检查过程。
              • navigator.languages” 已设置为默认 chrome 值 '["en-US", "en", "es"]'。

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

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

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

              【讨论】:

              • 这是否可能通过十六进制编辑器删除 $cdc 条目?
              【解决方案14】:

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

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

              【讨论】:

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

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

              实验 1:

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

              实验 2:

              1. 和以前一样,我从 Python 控制台打开浏览器和带有 Selenium 的网页。

              2. 这一次,我不使用鼠标单击,而是使用 Selenium(在 Python 控制台中)单击具有随机偏移量的相同元素。

              3. 链接打不开,但我被带到了一个注册页面。

              影响:

              • 通过 Selenium 打开网络浏览器并不妨碍我看起来像人类
              • 像人类一样移动鼠标不一定被归类为人类
              • 通过 Selenium 单击带有偏移量的内容仍会引发警报

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

              【讨论】:

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

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

              【讨论】:

              • 为什么最后一次尝试没有关闭?除了你能解释一下你的答案吗?
              【解决方案17】:

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

              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
              【解决方案18】:

              partial interface Navigator { readonly attribute boolean webdriver; };

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

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

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

              【讨论】:

              • “没有源代码很难说”..源代码是免费提供的
              • 我的意思是没有相关网站的源代码。很难说他们在检查什么。
              【解决方案19】:

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

              即使他们可以创建新的机器人,我们还是想出了一种方法来识别 Selenium 是他们正在使用的工具,所以我们阻止 Selenium no 无论他们在该机器人上迭代多少次。我们现在正在这样做 使用 Python 和许多不同的技术。一旦我们看到一个模式 从一种类型的机器人中出现,然后我们努力对 他们使用的技术并将其识别为恶意。

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

              • 这与您使用 selenium 执行的操作无关 - 一旦您导航到该站点,您就会立即被检测到并被禁止。我尝试在操作之间添加人为的随机延迟,在页面加载后暂停 - 没有任何帮助
              • 这也与浏览器指纹无关 - 在具有干净配置文件的多个浏览器中尝试过,而不是隐身模式 - 没有任何帮助
              • 因为根据采访中的提示,这是“逆向工程”,我怀疑这是通过在浏览器中执行的一些 JS 代码完成的,这表明这是一个通过 selenium webdriver 自动化的浏览器

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

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

              是的。


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

              【讨论】:

              • @RyanWeinstein 好吧,我们没有实际证据,我们只能推测和测试。现在,我想说他们有办法使用硒来检测我们。尝试使用 selenium 版本 - 这可能会给你一些线索。
              • 这可能与如何确定临时端口有关吗?该方法远离众所周知的范围。 github.com/SeleniumHQ/selenium/blob/…
              • Easyjet 正在使用 distilnetwork 服务,是的,它可以阻止虚拟机器人,但不能阻止复杂的机器人,因为我们已经测试了它每天来自不同 IP 的超过 2000 个请求(我们再次“相同”地重复使用这些请求)地址),所以基本上每个 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
              【解决方案20】:

              尝试将 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

              【讨论】:

                【解决方案21】:

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

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

                【讨论】:

                • 该属性仅在Firefox中添加。
                • 并且可以从控制浏览器的 selenium 扩展中删除它。无论如何它都会起作用。
                【解决方案22】:

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

                在文件 fingerprint_test.js 的 selenium 代码中对其进行测试,其中末尾的注释说“当前仅在 firefox 中实现”,但我无法通过一些简单的 @987654326 识别该方向的任何代码@ing,既不在当前 (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
                【解决方案23】:

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

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

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

                【讨论】:

                • 我已经用过那个网站,指纹和我的普通浏览器一样。我也没有自动化任何东西。我只是正常浏览。
                猜你喜欢
                • 1970-01-01
                • 2012-07-13
                • 2010-10-16
                • 2021-05-18
                相关资源
                最近更新 更多