【问题标题】:Python Selenium Unable to find an element inside Frameset > FramePython Selenium 无法在 Frameset > Frame 中找到元素
【发布时间】:2018-04-05 14:48:08
【问题描述】:

如何在以下 html 结构中找到突出显示的元素。

Target element highlighted

这是我正在使用的代码。

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


browser = webdriver.Edge()
browser.implicitly_wait(5) # seconds
browser.get(url) # aspx page

browser.find_element_by_id("LoginBtn").click()

browser.find_element_by_id("ReportingMenuName").click()
browser.find_element_by_id("EndpointDataExportSubmenuName").click()
browser.find_element_by_id("EndpointDataExportMenuItem").click()

browser.switch_to_default_content()

browser.switch_to.frame(browser.find_element_by_id("main"))

element = WebDriverWait(browser, 10).until(EC.presence_of_element_located(\
                       (By.ID, "ct100_PageBody_OkButton")))
element.click()

当我运行代码时,当它到达最后两行代码时出现此错误: 超时异常

如果我为此更改最后 2 行代码,则会收到另一个错误。

browser.find_element_by_id("ct100_PageBody_OkButton").click()

NoSuchElementException: 没有这样的元素

【问题讨论】:

  • 您可以尝试使用 find by selector 和值 "input[id$='OkButton']" ,而不是使用 find by id 。 . 因为,您可以切换到 id = main 的框架而不会遇到异常,并且您得到 No such element ,很可能 id 是动态的,我猜测 ct100 部分正在改变...考虑共享页面 url 如果它是一个公共站点。建议的选择器将匹配 id 以 OkButton 结尾的输入元素。
  • 一个选项是睡眠(2-3 秒取决于延迟)黑白切换到帧和预期的条件元素将解决这个问题。我也遇到过这个问题,但找不到更好的解决方案。
  • Nish26,你建议用户通过 css 选择器找到工作。谢谢你。我想知道您是如何得出元素 id 是动态的结论的?当你说动态是因为它可以在不同的会话中改变?当我用不同的浏览器检查元素时,它总是显示相同的 id。

标签: python python-3.x selenium selenium-webdriver webdriver


【解决方案1】:

您需要考虑以下几点:

  • 当您访问/登录到 url 时,Selenium 的焦点在 Top Level Browsing Context。所以在切换到任何 frame 之前你不需要switch_to_default_content()。因此,您可以省略该行:

    browser.switch_to_default_content()
    
  • 当您通过switch_to.frame() 切换到框架时,使用子句frame_to_be_available_and_switch_to_it 诱导WebDriverWait 以使框架 可用于切换,如下所示:

    WebDriverWait(browser, 10).until(EC.frame_to_be_available_and_switch_to_it((By.ID,"main")))
    
  • 一旦您在调用click() 时识别出向前移动的元素,就在框架内,因此您需要使用element_to_be_clickable 而不是expected_conditions 作为presence_of_element_located,如下所示:

    WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, "//input[@class='buttontext' and contains(@id,'_PageBody_OkButton')]"))).click()
    

【讨论】:

  • DebajanB,感谢您的回答。我尝试了您建议的更改。你是对的,不需要“switch_to_default_content()”。此外,对“EC.frame_to_be_available_and_switch_to_it”的更改有效;但是元素的选择不起作用。然而,当我像 Nish26 建议的那样使用“find_by_css_selector”时,它就起作用了。
  • @M.Rod 查看我更新的答案,让我知道状态。
猜你喜欢
  • 1970-01-01
  • 2018-01-10
  • 2018-08-01
  • 1970-01-01
  • 2022-09-30
  • 1970-01-01
  • 1970-01-01
  • 2013-09-16
相关资源
最近更新 更多