使用 Chrome 时的硒“selenium.common.exceptions.NoSuchElementException”

Posted

技术标签:

【中文标题】使用 Chrome 时的硒“selenium.common.exceptions.NoSuchElementException”【英文标题】:Selenium "selenium.common.exceptions.NoSuchElementException" when using Chrome 【发布时间】:2018-06-08 04:09:27 【问题描述】:

我正在尝试在 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】:

NoSuchElementException

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

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

NoSuchElementException基本抛出2种情况如下:

使用时:

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 应包含以下参数:

消息、屏幕、堆栈跟踪

    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 内。 您采用的 Locator Strategy 标识了元素,但由于存在属性 style="display: none;" 而不可见。 您采用的 Locator Strategy 不能唯一地 识别 HTML DOM 中的所需元素,目前还可以找到其他一些 隐藏 / 不可见 元素。 您尝试定位的 WebElement 位于 <iframe> 标记内。 WebDriver 实例甚至在 HTML DOM 中存在/可见元素之前就开始寻找 WebElement

解决方案

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

采用一个Locator Strategy 唯一标识所需的WebElement。您可以借助开发者工具 (Ctrl+Shift+IF12) 并使用元素检查器

这里有关于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="display: none;" 属性,通过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 与expected_conditions 设置为正确的方法如下:

等待presence_of_element_located

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

等待visibility_of_element_located

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

等待element_to_be_clickable

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

这个用例

您看到的是NoSuchElementException,因为 id 定位器没有唯一标识 canvas。要识别画布和上面的 click(),您必须等待 canvas 变为 clickable,然后您可以使用以下代码块:

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

参考

您可以在以下位置找到Selenium 的java 客户端相关讨论:

NoSuchElementException, Selenium unable to locate element

【讨论】:

我复制了错误的错误,我只是用正确的错误编辑了问题并实施了您的建议。我仍然遇到同样的错误。

以上是关于使用 Chrome 时的硒“selenium.common.exceptions.NoSuchElementException”的主要内容,如果未能解决你的问题,请参考以下文章

提交元素不可点击的硒python

如何分析每个单独的硒测试?

ExecuteScript 上的硒超时

请使用json逐步解释基本的硒配置[关闭]

Hover 属性的硒测试

使用python的不可靠的硒webdriver单击