Selenium webdriver: Modificación del indicador navigator.webdriver para evitar la detección de selenio

Resuelto Ajanth asked hace 6 años • 15 respuestas

Estoy intentando automatizar una tarea muy básica en un sitio web usando selenio y Chrome, pero de alguna manera el sitio web detecta cuando Chrome funciona con selenio y bloquea cada solicitud. Sospecho que el sitio web se basa en una variable DOM expuesta como esta https://stackoverflow.com/a/41904453/648236 para detectar el navegador impulsado por selenio.

Mi pregunta es, ¿hay alguna manera de hacer que el indicador navigator.webdriver sea falso? Estoy dispuesto a ir tan lejos como para intentar recompilar la fuente de selenio después de realizar modificaciones, pero parece que no puedo encontrar la fuente NavigatorAutomationInformation en ninguna parte del repositorio https://github.com/SeleniumHQ/selenium

Cualquier ayuda es muy apreciada

PD: también probé lo siguiente desde https://w3c.github.io/webdriver/#interface

Object.defineProperty(navigator, 'webdriver', {
    get: () => false,
  });

Pero solo actualiza la propiedad después de la carga de la página inicial. Creo que el sitio detecta la variable antes de que se ejecute mi script.

Ajanth avatar Oct 29 '18 12:10 Ajanth
Aceptado

Primero la actualización 1

execute_cdp_cmd(): Con la disponibilidad del execute_cdp_cmd(cmd, cmd_args)comando ahora puedes ejecutar fácilmenteherramientas-devtools-de-google-chrome Comandos usando Selenium . Con esta función, puede modificar navigator.webdriverfácilmente para evitar que se detecte Selenium.


Prevenir la detección 2

Para evitar que se detecte WebDriver impulsado por Selenium , un enfoque de nicho incluiría uno o todos los pasos mencionados a continuación:

  • Agregando el argumento --disable-blink-features=AutomationControlled

    from selenium import webdriver
    
    options = webdriver.ChromeOptions() 
    options.add_argument('--disable-blink-features=AutomationControlled')
    driver = webdriver.Chrome(options=options, executable_path=r'C:\WebDrivers\chromedriver.exe')
    driver.get("https://www.website.com")
    

Puede encontrar una discusión detallada relevante en Selenium. No se puede abrir una segunda página.

  • Girando elagente de usuarioa través execute_cdp_cmd()del comando de la siguiente manera:

    #Setting up Chrome/83.0.4103.53 as useragent
    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.53 Safari/537.36'})
    
  • Cambie el valor de propiedadnavigator de webdriver a indefinido

    driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
    
  • Excluir la colección de enable-automationinterruptores .

    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    
  • ApagaruseAutomationExtension

    options.add_experimental_option('useAutomationExtension', False)
    

Código de muestra 3

Siguiendo todos los pasos mencionados anteriormente y el bloqueo de código efectivo será:

from selenium import webdriver

options = webdriver.ChromeOptions() 
options.add_argument("start-maximized")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
driver = webdriver.Chrome(options=options, executable_path=r'C:\WebDrivers\chromedriver.exe')
driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
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.53 Safari/537.36'})
print(driver.execute_script("return navigator.userAgent;"))
driver.get('https://www.httpbin.org/headers')

Historia

Según el borrador del editor del W3C, la implementación actual menciona estrictamente:

El indicador se establece cuando el agente de usuario está bajo control remoto , que inicialmente está configurado en .webdriver-active truefalse

Más,

Navigator includes NavigatorAutomationInformation;

Cabe señalar que:

La NavigatorAutomationInformation interfaz no debe estar expuesta en WorkerNavigator .

La NavigatorAutomationInformation interfaz se define como:

interface mixin NavigatorAutomationInformation {
    readonly attribute boolean webdriver;
};

que devuelve truesi se establece webdriver-active la bandera , falso en caso contrario.

Finalmente, navigator.webdriverdefine una forma estándar para que los agentes de usuario cooperantes informen al documento que está controlado por WebDriver , de modo que se puedan activar rutas de código alternativas durante la automatización.

Precaución : alterar o ajustar los parámetros mencionados anteriormente puede bloquear la navegación y detectar la instancia de WebDriver .


Actualización (6 de noviembre de 2019)

A partir de la implementación actual, una forma ideal de acceder a una página web sin ser detectado sería usar la ChromeOptions()clase para agregar un par de argumentos a:

  • Excluir la colección de enable-automationinterruptores .
  • ApagaruseAutomationExtension

a través de una instancia de ChromeOptionsla siguiente manera:

  • Ejemplo de Java:

    System.setProperty("webdriver.chrome.driver", "C:\\Utility\\BrowserDrivers\\chromedriver.exe");
    ChromeOptions options = new ChromeOptions();
    options.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation"));
    options.setExperimentalOption("useAutomationExtension", false);
    WebDriver driver =  new ChromeDriver(options);
    driver.get("https://www.google.com/");
    
  • Ejemplo de Python

    from selenium import webdriver
    
    options = webdriver.ChromeOptions()
    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    options.add_experimental_option('useAutomationExtension', False)
    driver = webdriver.Chrome(options=options, executable_path=r'C:\path\to\chromedriver.exe')
    driver.get("https://www.google.com/")
    
  • Ejemplo de rubí

      options = Selenium::WebDriver::Chrome::Options.new
      options.add_argument("--disable-blink-features=AutomationControlled")
      driver = Selenium::WebDriver.for :chrome, options: options
    

Leyendas

1 : Se aplica únicamente a los clientes Python de Selenium.

2 : Se aplica únicamente a los clientes Python de Selenium.

3 : Se aplica únicamente a los clientes Python de Selenium.

undetected Selenium avatar Oct 29 '2018 07:10 undetected Selenium

Controlador Chrome :

¡Finalmente descubrí la solución simple para esto con una simple bandera! :)

--disable-blink-features=AutomationControlled

navigator.webdriver=true ya no aparecerá con esa bandera configurada.

Para obtener una lista de cosas que puedes desactivar, consúltalas aquí

010011100101 avatar Feb 25 '2020 21:02 010011100101

No utilice el comando cdp para cambiar el valor del controlador web, ya que generará una inconsistencia que luego se puede utilizar para detectar el controlador web. Utilice el siguiente código, esto eliminará cualquier rastro de webdriver.

options.add_argument("--disable-blink-features")
options.add_argument("--disable-blink-features=AutomationControlled")
Baki Billah avatar May 06 '2020 08:05 Baki Billah