python google-chrome selenium selenium-chromedriver chromium

python - Selenium "selenium.common.exceptions.NoSuchElementException" cuando se usa Chrome



google-chrome selenium-chromedriver (1)

Estoy tratando de jugar QWOP usando Selenium en Chrome, pero sigo recibiendo el siguiente error:

selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element {"method":"id","selector":"window1" (Session info: chrome=63.0.3239.108 (Driver info: chromedriver=2.34.522913 (36222509aa6e819815938cbf2709b4849735537c), platform=Linux 4.10.0-42-generic x86_64)

mientras usa el siguiente código:

from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains import time browser = webdriver.Chrome() browser.set_window_size(640, 480) browser.get(''http://www.foddy.net/Athletics.html?webgl=true'') browser.implicitly_wait(10) canvas = browser.find_element_by_id("window1") canvas.click() while (True): action = ActionChains(browser) action.move_to_element(canvas).perform() canvas.click() canvas.send_keys("q")

El mismo código funciona perfectamente en Firefox, pero debido a que quiero usar la capacidad de Chrome para ejecutar un juego webgl en modo sin cabeza, realmente no puedo cambiar a Firefox.

¿Alguna solución para que esto funcione?


NoSuchElementException

selenium.common.exceptions.NoSuchElementException conocido popularmente como NoSuchElementException se define como:

exception selenium.common.exceptions.NoSuchElementException(msg=None, screen=None, stacktrace=None)

NoSuchElementException se lanza básicamente en 2 casos de la siguiente manera:

  • Cuando usas :

    webdriver.find_element_by_*("expression") //example : my_element = driver.find_element_by_xpath("xpath_expression")

  • Cuando usas :

    element.find_element_by_*("expression") //example : my_element = element.find_element_by_*("expression")

Según los documentos de API, como cualquier otro selenium.common.exceptions , NoSuchElementException debe contener los siguientes parámetros:

  • msg, pantalla, stacktrace

    raise exception_class(message, screen, stacktrace) selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":".//*[@id=''create-portal-popup'']/div[4]/div[1]/button[3]"} (Session info: chrome=61.0.3163.100) (Driver info: chromedriver=2.32.498550 (9dec58e66c31bcc53a9ce3c7226f0c1c5810906a),platform=Windows NT 10.0.10240 x86_64)

Razón

El motivo de NoSuchElementException puede ser cualquiera de los siguientes:

  • La estrategia de localización que ha adoptado no identifica ningún elemento en el DOM HTML .
  • La estrategia de localización que ha adoptado no puede identificar el elemento, ya que no está dentro de la Viewport del navegador.
  • La estrategia de localización que ha adoptado identifica el elemento pero es invisible debido a la presencia del atributo style = "display: none;" .
  • La estrategia de localización que ha adoptado no identifica de forma exclusiva el elemento deseado en el DOM HTML y actualmente encuentra algún otro elemento oculto / invisible .
  • El elemento web que está intentando localizar está dentro de una etiqueta <iframe> .
  • La instancia de WebDriver está buscando el elemento web incluso antes de que el elemento esté presente / visible dentro del DOM HTML .

Solución

La solución para abordar NoSuchElementException puede ser una de las siguientes:

  • Adopte una estrategia de localización que identifique de forma exclusiva el elemento web deseado. Puede obtener ayuda de las Herramientas para desarrolladores ( Ctrl + Shift + I o F12 ) y usar el Inspector de elementos .

    Aquí encontrará una discusión detallada sobre cómo inspeccionar el elemento en selenium3.6 ya que firebug ya no es una opción para FF 56.

  • Use el método execute_script() para desplazar el elemento y verlo de la siguiente manera:

    elem = driver.find_element_by_xpath("element_xpath") driver.execute_script("arguments[0].scrollIntoView();", elem)

    Aquí encontrará una discusión detallada sobre Desplazarse hacia la parte superior de la página en Python usando Selenium

  • El elemento Incase tiene el atributo style = "display: none;" , elimine el atributo mediante el método executeScript() siguiente manera:

    elem = driver.find_element_by_xpath("element_xpath") driver.execute_script("arguments[0].removeAttribute(''style'')", elem) elem.send_keys("text_to_send")

  • Para verificar si el elemento está dentro de un <iframe> recorre el HTML hacia arriba para ubicar la etiqueta <iframe> respectiva y switchTo() el iframe deseado a través de cualquiera de los siguientes métodos:

    driver.switch_to.frame("iframe_name") driver.switch_to.frame("iframe_id") driver.switch_to.frame(1) // 1 represents frame index

    Aquí puede encontrar una discusión detallada sobre ¿Cómo puedo seleccionar un elemento html sin importar en qué marco se encuentre en selenio? .

  • Si el elemento no está presente / visible en el DOM HTML de inmediato, induzca WebDriverWait con el valor expected_conditions establecidas en el método adecuado de la siguiente manera:

    • Para esperar presence_of_element_located :

      element = WebDriverWait(driver, 20).until(expected_conditions.presence_of_element_located((By.XPATH, "element_xpath'']")))

    • Para esperar visibility_of_element_located :

      element = WebDriverWait(driver, 20).until(expected_conditions.visibility_of_element_located((By.CSS_SELECTOR, "element_css")

    • Para esperar a element_to_be_clickable :

      element = WebDriverWait(driver, 20).until(expected_conditions.element_to_be_clickable((By.LINK_TEXT, "element_link_text")))

Este caso de uso

Está viendo NoSuchElementException porque el localizador de id no identifica el lienzo de forma exclusiva. Para identificar el lienzo y click() en él, debe esperar a que se pueda clickable en el lienzo y para lograrlo, puede usar el siguiente bloque de código:

WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//canvas[@id=''window1'']"))).click()