1

I am trying to scrape some data from an iframe located within a webpage. The URL of the webpage is https://www.nissanoflithiasprings.com/schedule-service. I am trying to access the button shown in the image below:

enter image description here

When I right-click on the button (located inside the iframe) to view the source code, I am able to see the HTML id and name (see screenshot below):

enter image description here

The "id" for the button is "new_customer_button". However, when I use selenium webdriver's driver.find_element_by_id("new_customer_button") to access the button, the code is not able to locate the button inside the iframe and throws the following error:

NoSuchElementException: no such element: Unable to locate element: {"method":"id","selector":"new_customer_button"}

Below is the code that I have tried so far:

from selenium import webdriver
chrome_path = r"C:\Users\gh455\Downloads\chromedriver_win32\chromedriver.exe"
driver = webdriver.Chrome(chrome_path)
driver.get("https://www.nissanoflithiasprings.com/schedule-service")

dest_iframe = driver.find_elements_by_tag_name('iframe')[0] 
driver.switch_to.frame(dest_iframe)

driver.find_element_by_id("new_customer_button")

Not sure why this is happening. Any help will be appreciated. Thanks!

Guy
  • 46,488
  • 10
  • 44
  • 88
Siddharth Gosalia
  • 301
  • 1
  • 4
  • 18

2 Answers2

3

The element is inside multiple <iframe> tags, you need to switch to them one by one. You should also maximize the window and use explicit wait as it take some time to load

from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By

chrome_path = r"C:\Users\gh455\Downloads\chromedriver_win32\chromedriver.exe"
driver = webdriver.Chrome(chrome_path)
driver.maximize_window()
driver.get("https://www.nissanoflithiasprings.com/schedule-service")

wait = WebDriverWait(driver, 10)

# first frame - by css selector
wait.until(ec.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, '[src^="https://consumer.xtime.com"]')))

# second frame - by ID
wait.until(ec.frame_to_be_available_and_switch_to_it('xt01'))

driver.find_element_by_id("new_customer_button")
Guy
  • 46,488
  • 10
  • 44
  • 88
2

To click() on the element with text as Make · Year · Model as the the desired element is within an nested <iframe>s so you have to:

  • Induce WebDriverWait for the desired parent frame to be available and switch to it.
  • Induce WebDriverWait for the desired child frame to be available and switch to it.
  • Induce WebDriverWait for the desired element_to_be_clickable().
  • You can use the following solution:

    • Code Block:

      from selenium import webdriver
      from selenium.webdriver.support.ui import WebDriverWait
      from selenium.webdriver.common.by import By
      from selenium.webdriver.support import expected_conditions as EC
      
      chrome_options = webdriver.ChromeOptions() 
      chrome_options.add_argument("start-maximized")
      chrome_options.add_argument('disable-infobars')
      driver = webdriver.Chrome(options=chrome_options, executable_path=r'C:\WebDrivers\chromedriver.exe')
      driver.get("https://www.nissanoflithiasprings.com/schedule-service")
      WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe[src*='com/scheduling']")))
      WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe[src*='consumerportal']")))
      WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.button.button--action.btn.btn-secondary#new_customer_button"))).click()
      
  • Browser Snapshot:

nissan

Here you can find a relevant discussion on Ways to deal with #document under iframe

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352