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