¿Cómo puedo volver a conectarme al navegador abierto por webdriver con selenium?

Por alguna razón desconocida, mi navegador abre páginas de prueba de mi servidor remoto muy lentamente. Así que estoy pensando si puedo volver a conectarme al navegador después de salir del script, pero no ejecutar webdriver.quit() esto dejará el navegador abierto. Probablemente sea una especie de manejador de HOOK o webdriver. He buscado el documento API de selenium pero no encontré ninguna función. Estoy usando Chrome 62, x64, Windows 7, selenium 3.8.0. Seré muy apreciado si la pregunta puede ser resuelta o no.

No , no puede volver a conectarse a la sesión anterior del Web Browser después de abandonar el script. Incluso si puede extraer el Session ID , las Cookies y otros atributos de sesión de la Browsing Session anterior, no podrá pasar esos atributos como un GANCHO al WebDriver .

Una manera más limpia sería llamar a webdriver.quit() y luego abarcar una nueva Browsing Session .

Historia:

Anteriormente, hubo algunos debates e bashs de volver a conectar WebDriver a una sesión de navegación en ejecución existente. Puede encontrar las discusiones en estos QA:

  • Allow webdriver to attach to a running browser
  • [docs] webdriver.firefox.useExisting not implemented

Sin entrar en eso, ¿por qué crees que dejar una ventana abierta del navegador resolverá el problema de la lentitud, realmente no necesitas un control para hacerlo? Solo sigue ejecutando las pruebas sin cerrar la sesión o, en otras palabras, sin llamar a driver.quit() como te has mencionado. ¿La pregunta aquí es el marco que viene con su propio corredor? Como Pepino?

En cualquier caso, debe tener algún código de “configuración” y “limpieza”. Entonces, lo que debe hacer es garantizar durante la fase de “limpieza” que el navegador vuelva a su estado inicial. Eso significa:

  • Se muestra una página en blanco
  • Las cookies se borran para la sesión

Eso es realmente fácil de hacer: una sesión SE se representa mediante una url de conexión y session_id.

Descargo de responsabilidad : el enfoque es el uso de propiedades internas de selenium (“privadas”, en cierto modo), que pueden cambiar en las nuevas versiones; es mejor que no lo use para el código de producción; es mejor no ser utilizado contra el SE remoto (su hub, o proveedor como BrowserStack / Sauce Labs), debido a un drenaje de advertencia / recurso explicado al final.
Por ejemplo, no lo use en su caso particular, si no está realmente seguro de que lo necesita 🙂

Cuando se inicia una instancia de webdriver, debe obtener las propiedades antes mencionadas; muestra:

 from selenium import webdriver driver = webdriver.Chrome() driver.get('https://www.google.com/') # now Google is opened, the browser is fully functional; print the two properties # command_executor._url (it's "private", not for a direct usage), and session_id print(f'driver.command_executor._url: {driver.command_executor._url}') print(f'driver.session_id: {driver.session_id}') 

Con esos dos ahora conocidos, otra instancia puede conectarse; el “truco” es iniciar un controlador Remote y proporcionar el _url anterior, por lo que se conectará a ese proceso de selenium en ejecución:

 driver2 = webdriver.Remote(command_executor=the_known_url) # when the started selenium is a local one, the url is in the form 'http://127.0.0.1:62526' 

Cuando se ejecute, verá que se abre una nueva ventana del navegador. Esto se debe a que al iniciar el controlador, la biblioteca de selenium inicia automáticamente una nueva sesión (que comenzó en algún momento alrededor de Selenium3, aunque no estoy seguro de la hora exacta), y ahora tiene 1 proceso con 2 sesiones.

Si navega a una url, verá que se ejecuta en esa nueva instancia del navegador, no la que queda del inicio anterior, que no es el comportamiento deseado. En este punto, se deben hacer dos cosas: a) cerrar la sesión SE actual, yb) cambiar esta instancia a la sesión anterior:

 if driver2.session_id != the_known_session_id: # this is pretty much guaranteed to be the case driver2.close() # this closes the session's window - it is currently the only one, thus the session itself will be auto-killed, yet: driver2.quit() # for remote connections (like ours), this deletes the session, but does not stop the SE server # take the session that's already running driver2.session_id = the_known_session_id # do something with the now hijacked session: driver.get('https://www.bing.com/') 

Y eso es todo: ahora está conectado a la sesión anterior / ya existente, con todas sus propiedades (cookies, LocalStorage, etc.). No es necesario que proporcione las desired_capabilities al iniciar el nuevo controlador remoto, que se almacenan y heredan de la sesión existente que asumió.


Advertencia : tener un proceso SE funcionando puede llevar a un drenaje de recursos en el sistema.

Cada vez que se inicia y luego no se cierra, como en la primera parte del código, permanecerá allí hasta que lo mate manualmente. Con esto quiero decir, en Windows, por ejemplo, verá un proceso de “chromedriver.exe”, que debe terminar de forma manual una vez que haya terminado con él. No puede ser cerrado por un controlador que se haya conectado a él como a un proceso de selenium remoto.
El motivo: cada vez que inicia una instancia de navegador local y luego llama a su método de quit() , tiene 2 partes, la primera es eliminar la sesión de la instancia de Selenium (lo que se hace en el segundo código allí) y el otro es detener el servicio local (chrome / geckodriver), que generalmente funciona bien.

Lo que pasa es que, para las sesiones remotas, falta la segunda pieza: su máquina local no puede controlar un proceso remoto, ese es el trabajo del concentrador de ese control remoto. Entonces, esa segunda parte es literalmente una statement python de pass : una no-operación.

Si inicia demasiados servicios de selenium en un concentrador remoto y no tiene control sobre él, eso generará el drenaje de recursos de ese servidor. Los proveedores de la nube como BrowserStack toman medidas en contra de esto; están cerrando servicios sin actividad durante los últimos 60, etc., sin embargo, esto es algo que no desea hacer.

Y en cuanto a los servicios locales de SE, simplemente no olvides limpiar ocasionalmente el SO de los controladores huérfanos de selenium que olvidaste 🙂