in selenium web driver how to choose the correct i

2019-01-03 03:32发布

I'm trying to click on an element on this page:

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

At this point I would like to click on 'Cash Flow', 'Balance Sheet', or 'Quarterly'. I know these buttons have been loaded because I can extract them using BeautifulSoup from the page source. But when I try to do it using Selenium:

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

All return 'Unable to locate element' except for 'Quarterly' which returns an element but its the one sitting above the graph and not the one above the table which is what I'm interested in.

I think this is due to being in the wrong iframe, and I have located all iframes:

driver.find_elements_by_tag_name('iframe')

which returns 9 elements. But I'm having trouble figuring which iframe the elements I want to click on belong to. I also went through the iframes sequentially and still couldn't find the elements I'm interested in.

3条回答
放我归山
2楼-- · 2019-01-03 04:00

you need switch to correct iframe - all of them has different IDs (or some other tags) in java it looks like this (for some random iframe id)

driver.switchTo().frame(driver.findElementById("defaultdestFB2-1"))
查看更多
啃猪蹄的小仙女
3楼-- · 2019-01-03 04:09

I just checked in the website, they (the elements you are looking for) are NOT in any iframe tag.

Following code worked for me (changed to xpath, no need to switch):

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()

Note: It might be the reason that for "Financials", parent tag is a which represent a link, but for other elements (Cash Flow, Balance sheet), parent tag is div which is not a link tag. so find_element_by_link_text might not have been worked.


Switching between iframes:

You have to switch to the frame in which the element is present before we try to identify it.

Lets assume, your element is inside 3 iframes as follows:

<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>

Now, if you want to identify CashFlow which is inside the three iFrames:

    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()

Note: I used Frame References instead of indexes as you mentioned there are 9 iFrames. so, using indexes would be confusing. If you can't identify frameElement, then only go for indices.

Reference:

  1. http://selenium-python.readthedocs.io/api.html#selenium.webdriver.remote.webdriver.WebDriver.switch_to_frame
查看更多
Ridiculous、
4楼-- · 2019-01-03 04:15

Yes this helped resolve the issue. Thank you very much. There were 2 frames on this webpage (0) and (1). I added the line "driver.switch_to.frame(1)". Below is a copy of the code I used and it has fixed the issue I encountered...

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')
查看更多
登录 后发表回答