问题
I've been trying to enter to an iframe and write text in a search bar ( tag) in Safari:
I can't post the html because it's huge and it isn't mine but this is the iframe code:
<iframe frameborder="0" id="contentIFrame0" name="contentIFrame0" title="Área de contenido" style="border: 0px none; overflow: hidden; position: absolute; left: 0px; right: 0px; height: 100%; width: 100%; visibility: visible; display: block;"> (...Content of the iframe...) </iframe>
Here is python code:
wait.until(ec.frame_to_be_available_and_switch_to_it((By.XPATH, '//*[@id="contentIFrame0"]')))
chk_elem = wait.until(ec.visibility_of_element_located((By.XPATH, '//*[@id="2crmGrid_findCriteria"]')))
act = ActionChains(driver)
act.move_to_element(chk_elem)
act.send_keys('Search input', Keys.ENTER).perform()
but I always get this Exception: "selenium.common.exceptions.NoSuchFrameException: Message:".
I've been watching some tutorials and even reading the official documentation and I guess my code is Ok. Why it isn't working?
PD: There aren't another iframe before the iframe that I posted and XPATHs are well written. I don't know if it is relevant but we are talking about a web site of dynamics services from microsoft, just in case.
回答1:
This error message...
selenium.common.exceptions.NoSuchFrameException
...implies that Selenium driven WebDriver instance was unable to locate the <iframe>
element.
You have adapted the right approach. Ideally, to locate an iframe you have to induce WebDriverWait inconjunction with expected_conditions set as frame_to_be_available_and_switch_to_it().
However, there can be numerous reasons behind seeing this error and some of the reasons and solutions are as follows:
The desired iframe may be a nested iframe within it's parent iframe. In those cases you have to induce WebDriverWait first to switch to the parent iframe and then to the child iframe as follows:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"parent_iframe_xpath"))) WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"child_iframe_xpath")))
If you are switching between two sibling iframes then you first need to switch back to the
default_content
first and then switch to the sibling iframe as follows:WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"sibling_iframe_A"))) driver.switch_to.default_content() WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"sibling_iframe_B")))
You can find a detailed discussion in How to address “WebDriverException: Message: TypeError: can't access dead object” and wait for a frame to be available using Selenium and Python
At times multiple iframes can have similar values for same attributes. In those cases, you may need to construct Locator Strategies which identifies the
<iframe>
element uniquely using thesrc
attribute as follows:WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[@id="iframe_id and @src='iframe_src'"]")))
You can find a detailed discussion in Ways to deal with #document under iframe
Finally, you need to ensure that the binary versions are compatible and you can find a couple of relevant discussions in:
- Which Firefox browser versions supported for given Geckodriver version?
- How to work with a specific version of ChromeDriver while Chrome Browser gets updated automatically through Python selenium
- What is the correct IEDriverServer version to use with IE 11 through Selenium
The timeout configured for WebDriverWait may be too less and in that case you need to increase the timeout as follows;:
WebDriverWait(driver, 30).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"parent_iframe_xpath")))
Reference
You can find a couple of reference discussions in:
- Switch to an iframe through Selenium and python
- How can I select a html element no matter what frame it is in in selenium?
来源:https://stackoverflow.com/questions/60629144/selenium-python-selenium-common-exceptions-nosuchframeexception