1

I am new to Selenium for Python and was trying to locate element in multiple iframes. This is the DOM element I can see.

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>...</head>
    <body>
        <form>
        ...
           <div class="page">
               <div class="main clear" style="z-index: 20; position:relative;">
                   <div id="placeOrder">
                       <iframe src="BuyFlow.aspx" frameborder="0" width="1150" height="950">
                           #document
                               <html>
                                   <body>
                                       <form>
                                           ...
                                           <iframe id="CreativeLiftFrame">
                                               #document
                                                   <html>
                                                       ...
                                                       <body id="multiple-addresses">
                                                           ...
                                                       </body>
                                                   </html>
                                           </iframe>
                                        </form>
                                    </body>
                               </html>
                        </iframe>
                    </div>
                </div>
            </div>
        </form>
    </body>
</html>

What I want to do is to get the <body> tag's id name of second <iframe>.

That's "multiple-addresses".

In order to do that I have written my code as follows.

# Switch to the first iframe
iframe = driver.find_element(By.TAG_NAME, 'iframe')
driver.switch_to_frame(iframe)

# Fill in Address and ZipCode inputbox and submit form
address_input.send_keys(address)
postcode_input.send_keys(postcode)
postcode_input.send_keys(Keys.RETURN)

# Check Available - Inner iframe
second_iframe = WebDriverWait(driver, 30).until(EC.presence_of_element_located((By.TAG_NAME, 'iframe')))
driver.switch_to_frame(second_iframe)
print(second_iframe.get_attribute("id")
body = WebDriverWait(driver, 30).until(EC.presence_of_element_located((By.TAG_NAME, 'body')))
print(body.get_attribute("id")

As a result, I get 2 outputs on console.

CreativeLiftFrame
None

As you can see, selenium driver located the second iframe, but can't locate body tag's id in SECOND iframe.

I'm not sure how I can handle it.

8
  • I see two print statements in your code, and three lines of output. What is generating the error? Commented Feb 2, 2018 at 17:23
  • Hi, One is exception. Commented Feb 2, 2018 at 17:24
  • I understand, but what command is generating the exception? Commented Feb 2, 2018 at 17:25
  • I run the script as >>>python run.py. I mean the code above is snippet and the other code occurs exception. Commented Feb 2, 2018 at 17:25
  • The script you posted does not run at all ;) Commented Feb 2, 2018 at 17:28

2 Answers 2

1

In general, when navigating frames in Selenium, the following method is probably most reliable.

On every single frame change, go back to the root frame, or default:

driver.switch_to.default_content()
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, '//Some XPATH here')))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, '//Some Xpath here')))

In your case, switch to default, then switch to first child, then next child, and so on. On the next frame switch, repeat this - first to default, then to 1st child, etc.

I'd also add the you are searching for frames by tag_name, which is not very specific. How many tags with that tag_name are there in the whole document?

If there really is no unique id or name on that frame, you can search by the frame's src using something like this:

By.XPath("//iframe[contains(@src,'<src url here')]")
Sign up to request clarification or add additional context in comments.

Comments

1

As per the HTML you have shared to retrieve the id of the body tag of the second child <frame> you can use the following code :

# Switch to the first iframe
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[@src='BuyFlow.aspx']")))

# Fill in Address and ZipCode inputbox and submit form
address_input.send_keys(address)
postcode_input.send_keys(postcode)
postcode_input.send_keys(Keys.RETURN)

# Check Available - Inner iframe
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.ID,"CreativeLiftFrame")))
print(WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.TAG_NAME, 'body'))).get_attribute("id"))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.