pythonselenium-webdriveriframehidden

Selenium + Python : I cannot access element in iframe after using driver.switch_to.frame(iframe_id)


enter image description here

I am using python 3 and selenium in order to do some webscraping. I usually do not have any problem but this time, I have to access elements in an iframe.

I have been reading around and decided to follow the advises and switch frame and then, look for elements.

So here I switch frame :

iframe = driver.find_element(By.XPATH, "//iframe[contains(@id, 'ext-gen')]")
iframe_id = str(iframe.get_attribute('id'))

driver.switch_to.frame(iframe_id)

However, I cannot get the elements in this frame.

[Enter image description here](https://i.sstatic.net/ElaMS.png)

input_project = driver.find_element(By.XPATH, '//*[contains(@id, "b_s4_l1s4_ctl00_project_i")]')

Error stack trace:

Traceback (most recent call last):

 input_project = driver.find_element(By.XPATH, '//*[contains(@id, "b_s4_l1s4_ctl00_project_i")]')

  File ~\AppData\Local\anaconda3\lib\site-packages\selenium\webdriver\remote\webdriver.py:831 in find_element
    return self.execute(Command.FIND_ELEMENT, {"using": by, "value": value})["value"]

  File ~\AppData\Local\anaconda3\lib\site-packages\selenium\webdriver\remote\webdriver.py:440 in execute
    self.error_handler.check_response(response)

  File ~\AppData\Local\anaconda3\lib\site-packages\selenium\webdriver\remote\errorhandler.py:245 in check_response
    raise exception_class(message, screen, stacktrace)

NoSuchElementException: Unable to locate element: //*[contains(@id, "b_s4_l1s4_ctl00_project_i")]

Solution

  • I'm not sure why you are doing this

    iframe = driver.find_element(By.XPATH, "//iframe[contains(@id, 'ext-gen')]")
    iframe_id = str(iframe.get_attribute('id')) <<< why?
    
    driver.switch_to.frame(iframe_id)
    

    You already have the IFRAME element in iframe, just use that when switching frames. Also, add a wait to make sure that the frame is ready.

    iframe = driver.find_element(By.XPATH, "//iframe[contains(@id, 'ext-gen')]")
    wait = WebDriverWait(driver, 10)
    wait.until(EC.frame_to_be_available_and_switch_to_it(iframe))