Selenium webdriver: Modificación del indicador navigator.webdriver para evitar la detección de selenio
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.
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.webdriver
fá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 propiedad
navigator
de webdriver a indefinidodriver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
Excluir la colección de
enable-automation
interruptores .options.add_experimental_option("excludeSwitches", ["enable-automation"])
Apagar
useAutomationExtension
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
true
false
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 true
si se establece webdriver-active
la bandera , falso en caso contrario.
Finalmente, navigator.webdriver
define 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-automation
interruptores . - Apagar
useAutomationExtension
a través de una instancia de ChromeOptions
la 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.
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í
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")