0

I'm trying to download a link within a table after navigating to a page using Python3 + selenium. After using selenium to click through links, and inspecting the elements on the latest-loaded page, I can see that my element is within a frame called "contents". When I try to access this frame, however, upon calling:

DRIVER.switch_to_frame("contents")

I get the following error:

selenium.common.exceptions.NoSuchFrameException: Message: contents

To gain more context I applied an experiment. Both the page that I loaded using DRIVER.get(URL) and the one to which I navigated had a frame called "menu".
I could call DRIVER.switch_to_frame("menu") on the first page, but not on the second.

DRIVER = webdriver.Chrome(CHROME_DRIVER)
DRIVER.get(SITE_URL)
DRIVER.switch_to_frame("contents") # This works
target_element = DRIVER.find_element_by_name(LINK)
target_element.click()
time.sleep(5)
DRIVER.switch_to_frame("menu")
target_element = DRIVER.find_element_by_name(LINK2)
target_element.click()
target_element = DRIVER.find_element_by_name(LINK3)
target_element.click()
DRIVER.switch_to_frame("contents") # Code breaks here.
target_element = DRIVER.find_element_by_xpath(REF)
target_element.click()
print("Program complete.")

I expect the code to find the xpath reference for the link in the "contents" frame. Instead, when attempt to switch to the "contents" frame, python run-time errors and cannot find "contents".

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
phfb
  • 121
  • 2
  • 12

3 Answers3

3

selenium.common.exceptions.NoSuchFrameException: Message: contents

this is because you are staying in child level of iframe which is 'menu' so inside that it can't able to find the iframe 'contents'.

First Switch back to the parent frame which is "contents", by using

DRIVER.switch_to.default_content()

and then try to go to the 'contents' iframe and perform actions, Now it should work.

Saibharath
  • 56
  • 1
  • 6
1

Since contents appears to be a top level frame try going back to the top before selecting the frame:

DRIVER.switch_to.default_content()
DRIVER.switch_to.frame("contents")
jmq
  • 1,559
  • 9
  • 21
1

As a thumb rule whenever switching frames you need to induce WebDriverWait for frame_to_be_available_and_switch_to_it() and you need to:

  • Induce WebDriverWait for the desired frame to be available and switch to it.
  • Induce WebDriverWait for the desired element to be clickable.
  • You can use the following solution:

    target_element.click()
    WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"frame_xpath")))
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "REF"))).click()
    
  • You can find a detailed discussion on frame switching in How can I select a html element no matter what frame it is in in selenium?

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

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