selenium switch to iframe to locate elements

2019-07-23 06:33发布

问题:

selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.maximize_window()
driver.get("website")

driver.find_element_by_id("fld-username").send_keys("username")
driver.find_element_by_id("fld-password").send_keys("password")
driver.find_element_by_id("btn-inloggen").click()
driver.find_element_by_css_selector("div.block-position-top > p:nth-child(3) > a").click()

frame = driver.find_element_by_xpath("//iframe[@class='fancybox-iframe' and starts-with(@id,'fancybox-frame') and contains(@src,'/reminder/add/relation/')]")

WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(frame))
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//input[@class='submit button' and @id='btn-opslaan']"))).click()

driver.switch_to.default_content()

driver.quit()

Currently I'm getting the following error:

raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message: 

Which is making me assume that I haven't switched to the iframe correctly. I have tried numerous approaches with implicit and explicit waits.

this is the html of the frame: (i right clicked and copied element in chrome)

<div class="fancybox-wrap fancybox-desktop fancybox-type-iframe fancybox-opened" tabindex="-1" style="width: 960px; height: auto; position: fixed; top: 20px; left: 155px; opacity: 1; overflow: visible;"><div class="fancybox-skin" style="padding: 15px; width: auto; height: auto;"><div class="fancybox-outer"><div class="fancybox-inner" style="overflow: auto; width: 930px; height: 571px;"><iframe id="fancybox-frame1519030995343" name="fancybox-frame1519030995343" class="fancybox-iframe" frameborder="0" vspace="0" hspace="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen="" scrolling="auto" src="/reminder/add/relation/58048" kwframeid="1"></iframe></div></div><a title="Close" class="fancybox-item fancybox-close" href="javascript:;"></a></div></div>

some additional iframe elements if i open iframe source page: (button row block is where the locator is located which i want to click)

<body id="popup-body">
<h1>Toevoegen Agenda</h1><form method="POST" id="form-reminder-add-default" class="block-form" action="/reminder/add/relation/58048" ><input type="hidden" name="form-submit-id-default" id="fld-form-submit-id-default" value="form-reminder-add-default" /><input type="hidden" name="formNonce" id="fld-formNonce" value="ZTllOGNhZDdkOTZlYWM0NzVkZTI4NzI4NWE5MDAyZGI3NGMzZDEuNjU5ODY3ODY=" /><input type="hidden" name="id" id="fld-id" value="" /><input type="hidden" name="status" id="fld-status" value="0" /><div class="field-row">
<label for="fld-assignedTo">Toegewezen aan</label>

<div class="field-row">
<label for="fld-title">Onderwerp</label>
<div class="fld-required"><span>*</span></div>
<input type="text" name="title" id="fld-title" class="required" /><div id="status-fld-title" class="fld-status"><img src="/img/fieldicons/loader.gif" id="loader-fld-title"></div><div class="clear"><!-- empty --></div>
</div>

<div class="field-row">
<label for="fld-body" class="textarea">Opmerkingen</label>
<div class="fld-required"><!--no--></div>
<textarea  name="body" id="fld-body" class="tiny"></textarea><div id="status-fld-body" class="fld-status"><img src="/img/fieldicons/loader.gif" id="loader-fld-body"></div><div class="clear"><!-- empty --></div>
</div>

<div class="field-row">
<label for="fld-remindOn">Herinneren op</label>
<div class="fld-required"><span>*</span></div>
<input type="text" name="remindOn" id="fld-remindOn" class="required" value="23-02-2018" /><div id="status-fld-remindOn" class="fld-status valid"><img src="/img/fieldicons/loader.gif" id="loader-fld-remindOn"></div><span class="fieldtip">dd-mm-jjjj</span>
<div class="clear"><!-- empty --></div>
</div>

<div class="button-row"><p class="error submit-error-message"></p><p class="required-message">* = verplicht</p><input name="Opslaan" type="submit" id="btn-opslaan" class="submit button" value="Opslaan" /><input name="Annuleren" type="button" id="btn-annuleren" class="submit-sibling button" onclick="parent.history.back();  return false;" value="Annuleren" /><img src="/img/form-loader.gif" alt="loading" class="loading" /></div><div class="clear"></div></form>    </body>
</html>

element of a button i want to click to check if the switch to the frame went successful:

<input name="Opslaan" type="submit" id="btn-opslaan" class="submit button" value="Opslaan">

回答1:

As per your comment to click() on the element inside a frame you can use the following line of code :

WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//input[@class='submit button' and @id='btn-opslaan']"))).click()