使用Chrome时Selenium“selenium.common.exceptions.NoSuchElementException”

时间:2017-12-27 13:56:18

标签: python google-chrome selenium selenium-chromedriver chromium

我正在尝试在Chrome上使用Selenium播放QWOP,但我一直收到以下错误:

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)

使用以下代码时:

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")

相同的代码在Firefox上完美运行,但由于我想使用chrome的功能在无头模式下运行webgl游戏,我无法真正切换到Firefox。

要使其正常工作的任何变通方法吗?

1 个答案:

答案 0 :(得分:7)

NoSuchElementException

selenium.common.exceptions.NoSuchElementException俗称NoSuchElementException,定义为:

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

NoSuchElementException基本上按以下方式抛出:

  • 使用时:

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

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

根据API文档,与任何其他selenium.common.exceptions一样,NoSuchElementException应包含以下参数:

  • msg,screen,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)
    

原因

NoSuchElementException 的原因可能是以下任何一种:

  • 您采用的定位器策略并未识别HTML DOM中的任何元素。
  • 您采用的定位器策略无法识别该元素,因为它不在浏览器的Viewport内。
  • 您采用的定位器策略标识了该元素,但由于存在属性 style =" display:none;" 而不可见。
  • 您采用的定位器策略并非唯一标识 HTML DOM 中的所需元素,并且当前找到了其他< em>隐藏 / 不可见的元素。
  • 您尝试查找的 WebElement 位于<iframe>标记内。
  • 即使在 HTML DOM 中元素存在/可见之前, WebDriver 实例仍在寻找 WebElement

解决方案

解决 NoSuchElementException 的解决方案可以是以下任一种:

  • 采用唯一标识所需 WebElement Locator Strategy。您可以获取开发人员工具的帮助( Ctrl + Shift + I F12 )并使用 Element Inspector

    您可以在此处找到有关how to inspect element in selenium3.6 as firebug is not an option any more for FF 56?

  • 的详细讨论
  • 使用execute_script()方法滚动元素以进行查看,如下所示:

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

    您可以在此处找到有关Scrolling to top of the page in Python using Selenium

  • 的详细讨论
  • Incase元素具有属性 style =&#34; display:none;&#34; ,通过executeScript()方法删除属性,如下所示:

    elem = driver.find_element_by_xpath("element_xpath")
    driver.execute_script("arguments[0].removeAttribute('style')", elem)
    elem.send_keys("text_to_send")
    
  • 要检查该元素是否在<iframe>遍历 HTML ,以找到相应的<iframe>代码和switchTo()所需的 iframe 通过以下任一方法:

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

    您可以在此处找到有关How can I select a html element no matter what frame it is in in selenium?

  • 的详细讨论
  • 如果 HTML DOM 中的元素存在 / 可见,请使用{{WebDriverWait 3}}设置正确的方法如下:

    • 等待expected_conditions

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

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

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

此用例

您看到NoSuchElementException,因为 id 定位器并未唯一标识画布。要识别画布并在其上click(),您必须等待画布clickable,并且要实现这一点,您可以使用以下代码块:

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