【问题标题】:in selenium web driver how to choose the correct iframe在 selenium web 驱动程序中如何选择正确的 iframe
【发布时间】:2017-04-07 02:08:32
【问题描述】:

我正在尝试单击此页面上的一个元素:

url = 'https://finance.yahoo.com/quote/GOOG?ltr=1'
driver = webdriver.Firefox()
driver.get(url)
driver.find_element_by_link_text('Financials')

此时我想点击“现金流”、“资产负债表”或“季度”。我知道这些按钮已经加载,因为我可以使用 BeautifulSoup 从页面源中提取它们。但是当我尝试使用 Selenium 来做到这一点时:

driver.find_element_by_link_text('Cash Flow')
driver.find_element_by_link_text('Balance Sheet')
driver.find_element_by_link_text('Quarterly')

所有返回“无法定位元素”,除了“季度”返回一个元素,但它是位于图表上方的元素,而不是我感兴趣的表格上方的元素。

我认为这是由于在错误的 iframe 中,我已找到所有 iframe:

driver.find_elements_by_tag_name('iframe')

返回 9 个元素。但是我无法确定要单击的元素属于哪个 iframe。我也依次浏览了 iframe,但仍然找不到我感兴趣的元素。

【问题讨论】:

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


    【解决方案1】:

    我刚刚在网站上查看过,它们(您要查找的元素)在任何 iframe 标记中都

    以下代码对我有用(更改为 xpath,无需切换):

    driver.find_element_by_xpath("//span[contains(text(),'Cash Flow')]").click()
    driver.find_element_by_xpath("//span[contains(text(),'Balance Sheet')]").click()
    driver.find_element_by_xpath("//span[contains(text(),'Quarterly')]").click()
    

    注意:这可能是因为对于“财务”,父标签是a,代表一个链接,但对于其他元素(现金流量,资产负债表),父标签是@ 987654324@ 不是链接标签。所以find_element_by_link_text 可能没有工作。


    在 iframe 之间切换:

    在我们尝试识别它之前,您必须切换到该元素所在的框架。

    假设,您的元素位于 3 个 iframe 内,如下所示:

    <iframe name="frame1">
      <iframe name="frame2">
         <iframe name="frame3">
            <span>CashFlow</span> <! Span element is inside of 3 iframes>
        </iframe>
        <span>balance sheet> <! Span element is inside of 2 iframes>
      </iframe>
    </iframe>
    

    现在,如果您想识别三个 iFrame 中的 CashFlow:

        driver.switch_to_frame(driver.find_element_by_name("frame1")) // here, you can provide WebElement representing the iFrame or the index.
        driver.switch_to_frame(driver.find_element_by_name("frame2"))
        driver.switch_to_frame(driver.find_element_by_name("frame3"))
        driver.find_element_by_link_text("CachFlow")
    
        # switch to default frame before you again try find some other element which is not in the same frame (frame3)
    
       driver.switch_to_default_content()
    
       # then navigate to the frame that you want to indentify the element:
       driver.switch_to_frame(driver.find_element_by_name("frame1")) 
       driver.switch_to_frame(driver.find_element_by_name("frame2"))
       driver.find_element_by_link_text("balance sheet")
    
      # switch to default content again
      driver.switch_to_default_content()
    

    注意:我使用框架引用而不是索引,因为您提到有 9 个 iFrame。因此,使用索引会令人困惑。如果您无法识别 frameElement,则仅使用索引。

    参考:

    1. http://selenium-python.readthedocs.io/api.html#selenium.webdriver.remote.webdriver.WebDriver.switch_to_frame

    【讨论】:

    • 非常好的答案!因此,为了澄清,您将如何识别复杂网页上的框架是如何嵌套的?我一直在使用 Firefox 的 Inspector,尽管它对我来说并不明显,它如何让我找到 iframe 是如何相互包含的。
    • 您必须从要查找的元素开始遍历 html 标签的整个层次结构,并检查其父元素是否是 iframe 标签。 ,在上面的 html 中,你认为 required 元素在 iframe 标签中。如果语法是 ,那么我们认为 iframe 在同一行中是封闭的,并且没有任何元素。
    • 感谢您的回复,我理解您的解释,但我希望有一些网络工具可以轻松找到 iframe 的嵌套方式,而无需遍历所有代码?特别是如果源非常复杂,或者您是否建议我只需要通过眼睛来工作并找到合适的 iframe?
    • 在您的 Firefox 浏览器中使用 Firebug 和 FirePath 插件。导航到 Firebug 中的 FirePath 选项卡并检查元素。在表达式文本字段的左侧,下拉列表填充默认框架(顶部窗口)和其他子框架。从那里您可以确定您的元素属于哪个框架。但不是扁平化或分层结构。
    • 据我所知,我不知道有任何此类工具可以直接指出元素所在的 iframe 的层次结构。我建议在 stackoverflow.com 中提出一个新问题,因此,您可能会找到最佳答案。 @Mouli 已经提到了一种选择。
    【解决方案2】:

    您需要切换到更正 iframe - 它们都有不同的 ID(或其他一些标签) 在java中它看起来像这样(对于一些随机的iframe id)

    driver.switchTo().frame(driver.findElementById("defaultdestFB2-1"))
    

    【讨论】:

      【解决方案3】:

      是的,这有助于解决问题。非常感谢。此网页上有 2 个框架 (0) 和 (1)。我添加了“driver.switch_to.frame(1)”行。下面是我使用的代码的副本,它解决了我遇到的问题...

      import time
      from selenium import webdriver
      from selenium.webdriver.common.by import By
      from selenium.webdriver.common.keys import Keys
      from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
      
      #create capabilities
      capabilities = DesiredCapabilities.INTERNETEXPLORER
      
      #delete platform and version keys
      capabilities.pop("platform", None)
      capabilities.pop("version", None)
      
      #start an instance of IE
      driver = webdriver.Ie(executable_path="C:\\LocalDev\\IEDriverServer.exe", capabilities=capabilities)
      
      #open Accela login page
      driver.get("https://pwms-avdev.co.arapahoe.co.us/security/hostSignon.do?signOff=true")
      
      driver.switch_to.frame(1)
      
      #enter Agency
      agency = driver.find_element_by_id("servProvCode")
      agency.send_keys('arapahoe')
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多