Blog
Esperas de carga con Selenium
Aprender sobre las condiciones esperadas en WebDriver
Controlar diferentes tipos de esperas
Hoy en día la mayoría de las aplicaciones web están usando técnicas AJAX. Cuando el navegador carga una página, los elementos dentro de esa página pueden cargarse en diferentes intervalos de tiempo. Esto dificulta la localización de elementos: si un elemento todavía no está presente en el DOM, una función de localización mostrará una excepción ElementNotVisibleException. Usando las esperas, podemos resolver este problema. La espera proporciona cierta holgura entre las acciones realizadas – la mayoría de las veces localizando un elemento o cualquier otra operación con el elemento.
Selenium Webdriver ofrece dos tipos de espera – implícita y explícita. Una espera explícita hace que WebDriver espere a que se produzca una determinada condición antes de continuar con la ejecución. Una espera implícita hace que WebDriver sondee el DOM durante cierto tiempo al intentar localizar un elemento.
Esperaciones explícitas
Una espera explícita es un código que define para esperar a que se produzca una determinada condición antes de continuar con el código. El caso extremo de esto es time. sleep (), que establece la condición a un período de tiempo exacto para esperar. Hay algunos métodos de conveniencia que le ayudan a escribir el código que sólo esperará tanto tiempo como sea necesario. WebDriverWait en combinación con ExpectedCondition (EC) es una forma de lograrlo. Entonces en el siguiente ejemplo lo que haremos será crear una espera de 10 segundos sino encuentra el ID de main que obviamente tiene la web:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC driver = webdriver.Firefox(executable_path=r'C:\Users...añade tu ruta del... \geckodriver.exe') driver.get("https://unipython.com/") try: element = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "main"))) finally: driver.quit()
Esto espera hasta 10 segundos antes de lanzar una TimeoutException a menos que encuentre el elemento (main) para regresar dentro de 10 segundos. WebDriverWait llama de forma predeterminada a ExpectedCondition cada 500 milisegundos hasta que vuelve con éxito. Un retorno exitoso es para el tipo ExpectedCondition es un retorno booleano verdadero o no nulo valor de retorno para todos los demás tipos de ExpectedCondition. Por lo que si cambiamos el elemento a main5 veremos ese TimeoutException como vemos en el siguiente ejemplo:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC driver = webdriver.Firefox(executable_path=r'C:\Users...añade tu ruta del... \geckodriver.exe') driver.get("https://unipython.com/") try: element = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "main5"))) finally: driver.quit()
Condiciones Esperadas
Hay algunas condiciones comunes que se utilizan con frecuencia al automatizar los navegadores web. A continuación se enumeran los nombres de cada una. La unión de Selenium y Python proporciona algunos métodos convenientes para que no tenga que codificar usted mismo una clase de expected_condition o crear su propio paquete de utilidades para ellos.
- title_is
- title_contains
- presence_of_element_located
- visibility_of_element_located
- visibility_of
- presence_of_all_elements_located
- text_to_be_present_in_element
- text_to_be_present_in_element_value
- frame_to_be_available_and_switch_to_it
- invisibility_of_element_located
- element_to_be_clickable
- staleness_of
- element_to_be_selected
- element_located_to_be_selected
- element_selection_state_to_be
- element_located_selection_state_to_be
- alert_is_present
from selenium.webdriver.support import expected_conditions as EC wait = WebDriverWait(driver, 10) element = wait.until(EC.element_to_be_clickable((By.ID, 'someid')))
El módulo expected_conditions contiene un conjunto de condiciones predefinidas para utilizar con WebDriverWait.
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC driver = webdriver.Firefox(executable_path=r'C:\Users...añade tu ruta del... \geckodriver.exe') driver.get("https://unipython.com/") try: element = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.ID, 'main'))) finally: driver.quit()
Condiciones de espera personalizadas
También puede crear condiciones de espera personalizadas cuando ninguno de los métodos de conveniencia anteriores se ajuste a sus necesidades. Se puede crear una condición de espera personalizada utilizando un método __call__ que devuelve Falso cuando la condición no coincide.
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC driver = webdriver.Firefox(executable_path=r'C:\Users...añade tu ruta del... \geckodriver.exe') driver.get("https://unipython.com/") class element_has_css_class(object): #"Una expectativa para comprobar que un elemento tiene una clase de CSS en particular. # localizador - utilizado para encontrar el elemento devuelve el WebElement una vez #que tiene la clase css particular ". def __init__(self, locator, css_class): self.locator = locator self.css_class = css_class def __call__(self, driver): element = driver.find_element(*self.locator) # Finding the referenced element if self.css_class in element.get_attribute("class"): return element else: return False # Espera hasta que un elemento con id=' myNewInput' tenga clase' myCSSClass'. wait = WebDriverWait(driver, 10) element = wait.until(element_has_css_class((By.ID, 'main'), "stm_breadcrumbs_unit"))
Esperaciones implícitas
Una espera implícita le dice a WebDriver que sondee el DOM durante cierto tiempo cuando intente encontrar algún elemento (o elementos) que no esté disponible inmediatamente. El ajuste predeterminado es 0. Una vez configurado, la espera implícita se establece para la vida del objeto WebDriver.
from selenium import webdriver driver = webdriver.Firefox(executable_path=r'C:\Users...añade tu ruta del... \geckodriver.exe') driver.get("https://unipython.com") driver.implicitly_wait(10) # seconds continue_link = driver.find_element_by_class_name("stm_lms_log_in") continue_link.click()
➡ El manejo de esperas en páginas web nos permiten obtener todo en el contenido de la página ya que esperamos a que nuestro navegador complete la solicitud HTTP. Aprende mucho mas con nuestro curso de Selenium con Python donde se estudia este tema y muchos mas:
[…] ha añadido una espera de carga en la línea […]
[…] Esperas de varga de los lugares webs […]
[…] En la siguiente lección -> Esperas de varga de los lugares webs […]