Trusted answers to developer questions
Trusted Answers to Developer Questions

Related Tags

selenium
chrome
iframes
python

How to handle iframes using Selenium WebDriver

Rehan Jahangir

Grokking Modern System Design Interview for Engineers & Managers

Ace your System Design Interview and take your career to the next level. Learn to handle the design of applications like Netflix, Quora, Facebook, Uber, and many more in a 45-min interview. Learn the RESHADED framework for architecting web-scale applications by determining requirements, constraints, and assumptions before diving into a step-by-step design process.

The <iframe> is an HTML element that embeds another HTML page. In essence, it results in the nesting of multiple HTML pages inside the parent page. Each <iframe> has its session history and document. As such, they cannot be directly interacted with, via Selenium, unless we switch to them.

Note: The <iframe> has replaced <frame>. The use of the latter has been deprecated with HTML5. The following code examples can still be used with <frame> (if you are using a pre-HTML5 site) with some adjustments.

Take a look at the following code:

from selenium import webdriver
import time
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service

options = Options()
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)

driver.get("https://example.com")
hyperlink = driver.find_element(By.LINK_TEXT, "More information...").get_attribute("href")
time.sleep(5);
driver.get(hyperlink)

time.sleep(5)
driver.close();

We ask the script to:

  • Lines 1–6: Import necessary libraries.
  • Lines 8–10: Set two options that are required to make the script open Chrome properly in the 'Output' tab (while running this script). These options may not be necessary when using Selenium locally.
  • Line 12: Install and initialise Chrome.
  • Lines 14–17: Navigate to example.com, find the URL of the hyperlink (that has the text 'More information...'), and then navigate to that page after five seconds.
  • Lines 19–20: Wait another five seconds and then close the browser.

This is simple enough. Now, if we put example.com in an <iframe> (like we've done so in iFrame.html), we'll find that the previous code, used for getting the URL and navigating to it, will not work.

# We open up our own HTML page with an
# iframe instead of opening the site directly.
driver.get("file:///usercode/iFrame.html")

# Same code as in the previous widget.
hyperlink = driver.find_element(By.LINK_TEXT, "More information...").get_attribute("href")
time.sleep(5);
driver.get(hyperlink)

time.sleep(5)
driver.close();

Solution

We have to switch to the <iframe> in order to interact with the elements present in it. We can do this in two straightforward ways.

Store in a WebElement

We can find the <iframe> using any selector of our choice, store it, and then explicitly switch to it. The highlighted lines below show how we've used CSS_SELECTOR to find the <iframe>.

Note: If there are multiple <iframe> elements, we can index them to perform the task on the desired <iframe>. For example, if there are four <iframe> elements, we can get the third element by appending indexing like so, driver.find_element(By.CSS_SELECTOR, “iframe”)[2].

driver.get("file:///usercode/iFrame.html")

iframe = driver.find_element(By.CSS_SELECTOR, "iframe")
driver.switch_to.frame(iframe)

hyperlink = driver.find_element(By.LINK_TEXT, "More information...").get_attribute("href")
time.sleep(5);
driver.get(hyperlink)
time.sleep(5)

driver.close();

Refer to name or id

If the desired <iframe> has a name or id attribute, then it can be switched to directly by using either of them. If we look at the in iFrame.html, we'll see that the name attribute’s value is iframe_name. Simply provide this to driver.switch_to.frame() and we're good to go.

driver.get("file:///usercode/iFrame.html")

driver.switch_to.frame("iframe_name")

hyperlink = driver.find_element(By.LINK_TEXT, "More information...").get_attribute("href")
time.sleep(5);
driver.get(hyperlink)
time.sleep(5)

driver.close();

Don't forget to switch out

Finally, don't forget to switch out from the <iframe> to the main page, otherwise you'll be facing some rather nasty errors. We can do so easily by using the code in the highlighted line below.

Use the following script.py that:

  • Opens up the webpage.
  • Switches to the <iframe> present.
  • Finds and stores the URL of the hyperlink in, well, hyperlink.
  • Switches back to the main page.
  • Prints the stored URL.
  • Tries to grab the URL from the hyperlink again, this time outside of the <iframe>.

If we've been following along closely, we'll be able to tell at first glance, and even before running the code, that the 'Terminal' will exclaim that there's no such element to be found as the one in Line 11.

driver.get("file:///usercode/iFrame.html")

driver.switch_to.frame("iframe_name")
hyperlink = driver.find_element(By.LINK_TEXT, "More information...").get_attribute("href")

driver.switch_to.default_content()

# https://www.iana.org/domains/example
print(hyperlink)

driver.find_element(By.LINK_TEXT, "More information...").get_attribute("href")

time.sleep(15)
driver.close();

RELATED TAGS

selenium
chrome
iframes
python

CONTRIBUTOR

Rehan Jahangir
Copyright ©2022 Educative, Inc. All rights reserved

Grokking Modern System Design Interview for Engineers & Managers

Ace your System Design Interview and take your career to the next level. Learn to handle the design of applications like Netflix, Quora, Facebook, Uber, and many more in a 45-min interview. Learn the RESHADED framework for architecting web-scale applications by determining requirements, constraints, and assumptions before diving into a step-by-step design process.

Keep Exploring