Select iframe using Python + Selenium

后端 未结 6 640
Happy的楠姐
Happy的楠姐 2020-11-22 12:13

So, I was absolutely baffled as to how to do this in Selenium, and couldn\'t find the answer anywhere, so I\'m sharing my experience.

I was trying to select an ifram

相关标签:
6条回答
  • 2020-11-22 12:43

    You don't need to use JavascriptExecutor. All you needed to do was switch into the frame and then switch back out, like so:

    // do stuff on main window
    driver.switch_to.frame(frame_reference)
    // then do stuff in the frame
    driver.switch_to.default_content()
    // then do stuff on main window again
    

    As long as you are careful with this, you will never have a problem. The only time I always use a JavascriptExecutor is to get window focus since I think using Javascript is more reliable in that case.

    0 讨论(0)
  • 2020-11-22 12:43

    Selenium's selectFrame command accepts all the standard locators like css=, but it also has a an extra set of locators that work specifically with FRAME and IFRAME elements.

    As the doc says:

    selectFrame ( locator ) Selects a frame within the current window. (You may invoke this command multiple times to select nested frames.) To select the parent frame, use "relative=parent" as a locator; to select the top frame, use "relative=top". You can also select a frame by its 0-based index number; select the first frame with "index=0", or the third frame with "index=2".

    You may also use a DOM expression to identify the frame you want directly, like this: dom=frames["main"].frames["subframe"]

    Arguments: locator - an element locator identifying a frame or iframe

    In general, you'll have better luck using the specialized locators, especially if you establish the right context first (e.g., select_frame("relative=top"); select_frame("id=upload_file_frame");).

    0 讨论(0)
  • 2020-11-22 12:46

    This worked for me with Python (v. 2.7), webdriver & Selenium when testing with iframes and trying to insert data within an iframe:

    self.driver = webdriver.Firefox()
    
    ## Give time for iframe to load ##
    time.sleep(3)
    ## You have to switch to the iframe like so: ##
    driver.switch_to.frame(driver.find_element_by_tag_name("iframe"))
    ## Insert text via xpath ##
    elem = driver.find_element_by_xpath("/html/body/p")
    elem.send_keys("Lorem Ipsum")
    ## Switch back to the "default content" (that is, out of the iframes) ##
    driver.switch_to.default_content()
    
    0 讨论(0)
  • 2020-11-22 12:49

    If iframe is dynamic node, it's also possible to wait for iframe appearence explicitly and then switch to it using ExpectedConditions:

    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.support.ui import WebDriverWait as wait
    
    driver = webdriver.Chrome()
    driver.get(URL)
    wait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it("iframe_name_or_id"))
    

    If iframe doesn't have @id or @name it can be found as common WebElement using driver.find_element_by_xpath(), driver.find_element_by_tag_name(), etc..:

    wait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(driver.find_element_by_xpath("//iframe[@class='iframe_class']")))
    

    To switch back from iframe:

    driver.switch_to.default_content()
    
    0 讨论(0)
  • What finally worked for me was:

            sel.run_script("$('#upload_file_frame').contents().find('img[alt=\"Humana\"]').click();")
    

    Basically, don't use selenium to find the link in the iframe and click on it; use jQuery. Selenium has the capability to run an arbitrary piece of javascript apparently (this is python-selenium, I am guessing the original selenium command is runScript or something), and once I can use jQuery I can do something like this: Selecting a form which is in an iframe using jQuery

    0 讨论(0)
  • 2020-11-22 13:02

    you can use this simple code to look for the iframe using xpath

    sample use set_iframe("/html/body/div[2]/table/")

    def set_iframe(xpath):
        print('set_iframe')
        driver.switch_to.default_content()
        seq = driver.find_elements_by_tag_name('iframe')
        for x in range(0, len(seq)):
            driver.switch_to.default_content()
            print ("iframe-"+str(x))
            try:
                driver.switch_to.frame(int(x))
                driver.find_element_by_xpath(xpath)
                return str(x)
            except:
                continue
    
    0 讨论(0)
提交回复
热议问题