【问题标题】:Selenium Webdriver with Python - NoSuchWindowException after using frame_to_be_available_and_switch_to_it()Selenium Webdriver with Python - 使用 frame_to_be_available_and_switch_to_it() 后出现 NoSuchWindowException
【发布时间】:2021-04-14 00:54:24
【问题描述】:

我正在尝试通过 Python 使用 Selenium Webdriver,自动化 Chrome 浏览器。

在重新优化我的代码时,我试图摆脱任何time.sleep() 命令并尽可能使用隐式和显式等待。

我坚持的部分是 iframe / 模态对话框 - 切换到它之后,我仍然需要等待模态对话框加载,然后才能与元素交互而不会出错。

有效的代码:

driver.find_element(By.ID, "process").click()   # Process form button - creates modal dialog
time.sleep(2)                                   # Delay to wait for the frame to load
driver.switch_to.frame("acsframe")              # acsframe is the ID of the modal dialog
driver.find_element(By.CSS_SELECTOR, r'input.btn.btn-warning').click() # Cancel button

我要开始工作的代码:

driver.find_element(By.ID, "process").click() # Process form button
WebDriverWait(driver, 5).until(EC.frame_to_be_available_and_switch_to_it((By.ID, "acsframe")))
WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.CSS_SELECTOR, r'input.btn.btn-warning')))
driver.find_element(By.CSS_SELECTOR, r'input.btn.btn-warning').click() # Cancel button

错误信息:

NoSuchWindowException                     Traceback (most recent call last)
<ipython-input-24-acf8921ff08a> in <module>
      2 WebDriverWait(driver, 5).until(EC.frame_to_be_available_and_switch_to_it((By.ID, "acsframe")))
----> 3 WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.CSS_SELECTOR, r'input.btn.btn-warning')))
      4 driver.find_element(By.CSS_SELECTOR, r'input.btn.btn-warning').click()

我不明白我如何/为什么会在此处收到错误消息。我切换到第 2 行的框架,第 3 行工作大约 10 次,否则会引发错误。我知道元素定位器是正确的,因为它在第一个示例中有效。如果time.sleep() 有效,为什么这无效?

我尝试在 XPATH 和 CSS 选择器之间进行更改以定位元素,结果相同。按钮没有任何 ID。

更新:此代码也有效:

driver.find_element(By.ID, "process").click() # Process form button
time.sleep(2)
WebDriverWait(driver, 5).until(EC.frame_to_be_available_and_switch_to_it((By.ID, "acsframe")))
WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.CSS_SELECTOR, r'input.btn.btn-warning')))
driver.find_element(By.CSS_SELECTOR, r'input.btn.btn-warning').click()

因此,等待帧之前的延迟似乎可以修复它 - 但这不就是等待帧可用的命令的全部目的吗?我仍然想要一种方法来让它在没有time.sleep() 的情况下工作。

Screenshot of the relevant HTML

【问题讨论】:

    标签: python selenium selenium-webdriver iframe webdriverwait


    【解决方案1】:

    由于元素位于 &lt;iframe&gt; 内,因此您必须:

    • 诱导WebDriverWait 使所需的帧可用并切换到它

    • 诱导WebDriverWait 使所需的元素可点击

    • 您可以使用以下Locator Strategies

      driver.find_element(By.ID, "process").click() # Process form button
      WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.ID, "acsframe")))
      WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, r'input.btn.btn-warning'))).click()
      

    参考

    您可以在以下位置找到一些相关讨论:

    【讨论】:

    • 感谢您的回答。这在功能上与我所做的不一样吗?它抛出相同的 NoSuchWindowException - 似乎无法找到 iframe。它在第一个 WebDriverWait 之前使用 time.sleep(2)。
    • @Adam 您的代码和我提供的代码之间存在差异。但是,由于您没有提供相关的 HTML,我们确实无法测试代码。
    • 我添加了一些相关 HTML 的屏幕截图 - 也许从中可以清楚地看出为什么它只适用于 time.sleep? iframe 需要一秒钟才能加载到网页中。
    猜你喜欢
    • 1970-01-01
    • 2021-10-25
    • 2018-01-20
    • 2015-07-12
    • 2014-03-03
    • 2021-07-12
    • 1970-01-01
    • 1970-01-01
    • 2017-10-15
    相关资源
    最近更新 更多