pythonselenium-webdriver

Switching to Iframe with rotating ID Selenium


I am trying to access the login iframe from https://www.steelmarketupdate.com/. Previously I was able to access this via XPATH

client.switch_to.frame(client.find_element(By.XPATH, "/html/body/div[6]/div/iframe"))

However this is no longer working. I found the length of all iframe elements to be 6, and I am unable to access any of these even via the index location. How can I switch to this frame?


Solution

  • Try this:

    # This relative XPath expression locates the <iframe> element which contains value piano in the ID attribute
    By.XPATH, "//iframe[contains(@id,'piano')]"
    

    or this:

    # This is an XPath expression which locates the 3rd <iframe> element from top of the DOM
    By.XPATH, "(//iframe)[3]"
    

    Full line of code:

    client.switch_to.frame(client.find_element(By.XPATH, "//iframe[contains(@id,'piano')]"))
    

    UPDATE: Full code with selenium's waits to effectively locate elements. Code explaination in comments.

    import time
    from selenium import webdriver
    
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.common.by import By
    
    driver = webdriver.Chrome()
    driver.get("https://www.steelmarketupdate.com/")
    driver.maximize_window()
    wait = WebDriverWait(driver, 10)
    
    # click on Log In button
    wait.until(EC.element_to_be_clickable((By.XPATH, "(//li[@id='pp-subs-login'])[1]"))).click()
    
    # enter inside IFRAME
    wait.until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//iframe[contains(@id,'piano')]")))
    
    # send keys to email and password fields
    wait.until(EC.element_to_be_clickable((By.NAME, "email"))).send_keys("testEmail")
    wait.until(EC.element_to_be_clickable((By.XPATH, "//input[@aria-label='password']"))).send_keys("testPassword")
    
    # switch to default content
    driver.switch_to.default_content()
    
    # wait for a while to observe the result
    time.sleep(10)
    

    Result:

    enter image description here