I'm having problem selecting the iframe and accessing the different elements inside it. The iframe name is dynamically generated (e.g. frame11424758092173 or frame0005809321 or frame32138092173). The problem is that Selenium can't find the iframe no matter what i do....
switching to most recent frame doesn't work:
iframe = driver.find_elements_by_tag_name('iframe')[0]
driver.switch_to_frame(iframe)
Waiting for frame gets a timeout exception:
try:
iframe = WebDriverWait(driver, 5).until(EC.frame_to_be_available_and_switch_to_it(By.TAG_NAME('iframe')))
except:
logger.error(traceback.format_exc())
The following lines of code also times out:
try:
iframe = WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.TAG_NAME, u"iframe")))
driver.switch_to_frame(iframe)
except:
logger.error(traceback.format_exc())
I have also tried iterating through the frames but it can't find it. The returned list is empty
iframes = driver.find_elements_by_tag_name('iframe')
#iframes is empty
really need some help...
Have you tried locating the iframe by its XPath and using the contains method?:
iframe = driver.find_element_by_xpath('//iframe[contains(#name, "frame")]')
driver.switch_to_frame(iframe)
Now you can access elements within the iframe.
To exit the iframe use:
driver.switch_to_default_content()
The contains method lets you get an element by a partial attribute value. Pretty useful for dynamically generated IDs, names, etc. You can search by other attributes as well using XPath. For example, say your iframe element has the attribute value = "3". You could use:
iframe = driver.find_element_by_xpath('//iframe[contains(#name, "frame")][#value = "3"]')
driver.switch_to_frame(iframe)
This approach can be used with any number of attributes as well.
You could also try getting the element by its selector. Keep in mind that this limits what you can do with it:
driver.execute_script('document.querySelector("INSERT SELECTOR HERE").doSomething();')
To get the Selector and/or XPath you're going to want to inpect the element using your browser (Chrome in my case). Right click on the element. Click Inspect. Then right click on the HTML element and click Copy > Copy Xpath or Copy > Copy Selector.
If that doesn't work for me, my last resort is to go the url of the iframe.To get that, you need to right-click on the area of the webpage where the iframe exists and click View Frame Source. It'll then lead you to a new page. The url of that page will be shown in the top of the browser after view-source:. You can then simply navigate to that url:
driver.get('insert url of iframe here')
And now you have access to the elements within the iframe. I do not recommend this approach if you are manipulating elements within the iframe and then exiting the iframe. Your changes will get lost. This will only work if you are scraping info off of that iframe, NOT if you are manipulating the elements within. Finding the iframe element and switching into it is usually better and safer.
Related
Does anyone know what the message Element maybe inside frame from different src means?
I was trying to switch to frame and python selenium is not recognizing the element.
See screen shot of iframe path and message I see.
Below is what I see and getting timeout exception though page is loaded within waitime
WebDriverWait(driver, 20).until(E.frame_to_be_available_and_switch_to_it((By.NAME,
'gsft_main')))
[![See below pic][1]][1]
Try with ID or css selector
WebDriverWait(driver, 20).until(E.frame_to_be_available_and_switch_to_it((By.ID,
'gsft_main')))
or
WebDriverWait(driver, 20).until(E.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,
'iframe#gsft_main')))
or
WebDriverWait(driver, 20).until(E.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,
'iframe[title="Main Content"]')))
I'm facing an issue locating the element on screen when there are no unique identifiers like ID, text etc. As it opens URL, I need to scroll down and click on button - 'Get Started' to proceed!...
Below is my code:
global driver
driver = webdriver.Chrome(ChromeDriverManager().install())
driver.maximize_window()
driver.get("https://My URL")
driver.implicitly_wait(10)
screen = driver.find_element(By.XPATH, '//div[#class="swiper-wrapper"]')
screen.click() (- This step doesnt through any error, i tried using this to scroll down the screen)
element = driver.find_element(By.XPATH, '//span[contains(text(),"Get Started")]')
driver.execute_script("arguments[0].scrollIntoView(true);", element )
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//span[contains(text(),"Get Started")]'))).click()
or
element.click()
Please help me in determining how to locate the element.
enter image description here
In this case you are trying to find span which is inside #shadow-root, Selenium won't be able to click elements inside #shadow-root in easy way. Look here: How to click button inside #shadow-root (closed) using Selenium and Python
But in your case you probably don't need/want to click this specific span, becouse you have custom element ion-button, which has some click event listener attached to it.
You can check XPATH value in browser devtools. If you go to Elements tab, you can right click desired element and choose option Copy>Copy Xpath. Also make sure your element is not inside iframe tag, it could cause problem as well.
Currently I'm attemping to switch from my default content, to the only iframe in the website. I don't know if it's how the site is coded, but I can't access via DOM any element.
This is the HTML structure of the site:
XPATH of site is //*[#id="iframeBody"] (When I paste this in the element inspector, I get the correct iframe). So, if I try to switch using frame_to_be_available_and_switch_to_it, this is the output:
try:
WebDriverWait(self.driver, 10).until(ec.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[#id='iframeBody' and #name='body']")))
except Exception as e:
print(e)
>>> Message: javascript error: Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'.
>>>(Session info: chrome=79.0.3945.88)
I also tried creating an iframe element variable, finding it via ID and XPATH and then I've used switch_to(element). Getting the same result. When I print this variable, the element is actually found:
# Also tried finding with id
element = self.driver.find_element_by_xpath('//iframe[#id='iframeBody')
print(element)
<selenium.webdriver.remote.webelement.WebElement (session="9184691b1fdcccc15dd36bbcb914ac8b", element="1ef77729-8a6e-4d3c-98bd-c95878437585")>
But when I try to switch to this iframe, I get the same result as above.
For some reason, this site is not letting me use the DOM data, actually, when I try to click a button I need to use action chains, because I get the same error.
Anybody can help me?
Did you put enough time before switching ?
also, you could directly switch as well:
driver.switch_to.default_content()
driver.switch_to.frame(driver.find_element_by_id("iframeBody"))
I'm trying to scrape the following URL: https://www.vivareal.com.br/venda/sp/holambra/imovel-comercial_comercial/. It has two pages only. However, there is a button in the bottom which I can locate via XPATH: "//*[contains(#title, "Página anterior")]".
I'm trying to set a variable for when the button is not clickable, like:
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[contains(#title, "Página anterior")]')))
But it returns an element, even if the element is not clickable (I'm testing manually too). Is there any sugestions? Thanks!
When the button is not clickable, it has an attribute called data-disabled; otherwise that attribute is missing. The attribute has no value, but if you use the following CSS Selector it should grab that element only if there is no data-disabled attribute:
driver.find_element_by_css_selector('a[title="Página anterior"]:not([data-disabled]')
hi team,
I am trying to access a dynamic drop down with div as tag but I an able find it but not interact with it
as it changes its style type as shown below.
<div style ="display :none;"></div>"
to
<div style ="display :block;"></div>"
I am unable to click on this, please have a look into the screenshot for detail.
Info you have to click on the element to access this dynamic dropdown,
div is not clickable object in HTML. If it has assigned some JavaScript code to display when you click it then you may need also JavaScript to click it
driver.execute_script("arguments[0].click()", item)
and the same way you can change style
driver.execute_script("arguments[0].style.display = 'block';", item)
In this minimal working example I remove all img on this page.
from selenium import webdriver
url = 'https://stackoverflow.com/questions/65931008/unable-to-interact-with-this-dynamic-drop-down-using-python-selenium'
driver = webdriver.Firefox()
driver.get(url)
all_items = driver.find_elements_by_xpath('//img')
for item in all_items:
print(item.text)
#driver.execute_script("arguments[0].click()", item)
driver.execute_script("arguments[0].style.display = 'none';", item)
Solution -> actually the element we are looking here is masked element which means actual Id of this element is diff so by chance I am able to find it( for this you have go through HTML code row by row and find it, quiet a static way to do but that's how I did it) and place it in the code.
please do comment if you know more efficient way to work around masked elements.
Regards,
Anubhav