在selenium web驱动程序中如何选择正确的iframe

时间:2016-11-23 07:10:59

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

我试图点击此页面上的元素:

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,仍然无法找到我感兴趣的元素。

3 个答案:

答案 0 :(得分: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代表一个链接,但是对于其他元素(现金流量,资产负债表),父代码是div,它不是链接标记。所以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>

现在,如果你想识别三个iFrames中的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()

注意:我使用了Frame References而不是索引,因为你提到有9个iFrame。所以,使用索引会让人感到困惑。如果你不能识别frameElement,那么只去索引。

参考:

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

是的,这有助于解决问题。非常感谢你。该网页上有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')