How can I switch to the iframe using Selenium and python? - python

I've used Selenium for a number projects without problems. This one, however, no dice.
I'm trying to automate a check out process, and sometimes there is a prompt to re-input information. The window has a javascript popup (I think), and, while I can select the <div id="app"> portion without any problems, I CANNOT get find the iframe and focus on it.
So, this works:
driver.find_elements_by_id('app')
But, nothing works to recognize the frame and switch to it. For example, none these work:
driver.find_element_by_id()
driver.find_element_by_name()
driver.find_element_by_xpath()
And, I assume that because I can't find and switch to the iframe.
Help?

The element with the text as E-Mail Login is within an <iframe> so you have to:
Induce WebDriverWait for the desired frame to be available and switch to it.
You can use either of the following Locator Strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe.zoid-visible[title='ec_payment'][name^='__zoid__ec__payment']")))
Using XPATH:
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[#class='zoid-visible' and #title='ec_payment'][starts-with(#name, '__zoid__ec__payment')]")))
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Reference
You can find a couple of relevant discussions in:
Ways to deal with #document under iframe
Switch to an iframe through Selenium and python
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element while trying to click Next button with selenium
selenium in python : NoSuchElementException: Message: no such element: Unable to locate element

driver.switch_to.frame(iframe_elem)
or
driver.switch_to_frame(iframe_id)
in your case you can use :
driver.switch_to.frame(driver.find_element_by_tag_name("iframe"));
to switch back to main use:
driver.switch_to_default_content()

Try this code to switch to frame
frame = driver.find_element_by_xpath('//div[starts-with(#id, "zoid-ec-payment")]/iframe')
driver.switch_to.frame(frame)

Related

Selenium Element not interactable - python

I wrote a simple application in python, but when trying to click a button, I get an error Element not interactable. Here is a part of the code where it happens. I did wait for the element to render.
WebDriverWait(driver, 60).until(EC.presence_of_element_located((By.XPATH, '//*[#id="root"]/div[2]/div/div/div[2]/ul/li/button')))
driver.find_element(By.XPATH, '//*[#id="root"]/div[2]/div/div/div[2]/ul/li/button').click()
The error happens on this website: https://magiceden.io/ when clicking Connect Wallet in the top right corner and then trying to click Phantom in the opening window.
Reason behind this exception:
“element not interactabe” exception may occur due to various reason.
Element is not visible
Element is present in off screen (After scroll down it will display)
Element is present behind any other element
Element is disable
For your case it's locator, you can use below locator to click on it.
XPATH
//header/nav[1]/div[2]/div[2]/div[1]/button[2]
OR
//button[contains(#xpath,'1')]
OR
(//button[contains(.,'Connect Wallet')])[1]
The Syntax should be like
element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "myXpath")))
element.click();
Imports
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
I have tested with First and third XPATH, it's working for me, let me know if this does not solve your issue.

Selenium - Not able to find Button Element in HTML code

I have just started learning Selenium and was playing around a bit trying to automate a search on the secondhand clothing website vinted.fr.
I was able to find all necessary Elements in the HTML code, except one: -The Button to change the "sort by" functionality to "newest". (
This is a Screenshot of the Page including the Button I want to press)
Now I am wondering, what the Problem might be:-Is it possible, that the button is not having a "button" tag in the HTML code. If yes how do I find and click this element?-Am I just searching at wrong position?
Here is the HTML source code where I suggest the button element to be in:
To click on the element to set sort by functionality to newest you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "ul.pile li:nth-of-type(4) label"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//ul[#class='pile']//li[#class='pile__element'][last()]//label"))).click()
Note: You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

How to click this button using Selenium through Python

I cant click on a button on a webpage using selenium. Does anyone know how i can click it, I've tried every single method i can think of and i cant quite get it to work.
I've tried XPATH, ID's, searching for the text on the button, i've tried copy pasting code from other people.
This is the button i want to press:
<div id="sbWatchHeaderNext">
Next
</div>
This is the code I currently have that isn't working:
WebDriverWait(driver, 3).until(EC.presence_of_element_located((By.XPATH, "//button[contains(text(),'Continue Watching')]")))
and
driver.find_element_by_xpath("//button[contains(text(),'Next')]").click()
Please if you have any suggestions i should try, let me know :)
With some methods i would get absolutely no errors in console but nothing would happen on the webpage, and with others i would get "Message: no such element: unable to locate element:..." and things like that in my console.
Seems you were pretty close. To click() on the desired element you have to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following solutions:
Using LINK_TEXT:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.LINK_TEXT, "Next"))).click()
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div#sbWatchHeaderNext>a[href^='https://pf.entertainow.com//f/p/enter?plid']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[#id='sbWatchHeaderNext']/a[starts-with(#href, 'https://pf.entertainow.com//f/p/enter?plid') and text()='Next']"))).click()
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

How to Find Element Text within <span> using Selenium?

I am pretty new to Python and Selenium, and I have got my script to do what I want so far, but I have this current coding from the website:
<a onclick="realPostBack('ctl00$ctl00$mainContent$ContentPlaceHolder1$ucHub$ucSearchExplorer$dgContents$ctl00$ctl04$lnkContent', ''); return false;" id="ctl00_ctl00_mainContent_ContentPlaceHolder1_ucHub_ucSearchExplorer_dgContents_ctl00_ctl04_lnkContent" class="hub-content-item" actiontype="Secondary" href="javascript:__doPostBack('ctl00$ctl00$mainContent$ContentPlaceHolder1$ucHub$ucSearchExplorer$dgContents$ctl00$ctl04$lnkContent','')"><span>How to Project Wirelessly in Philly</span></a>
and I can't get it to click the link.
I've tried:
driver.find_element_by_text("How to Project Wirelessly in Philly")
and partial text
driver.find_element_by_id("ctl00_ctl00_mainContent_ContentPlaceHolder1_ucHub_ucSearchExplorer_dgContents_ctl00_ctl04_lnkContent")
I've tried by tag but all returning errors. Looking up on here, I've seen stuff with Xpath but I have no clue how to do that, but if someone here does, then a little help with that, or any other simple code that hopefully allows me to click that link. (I know i will have to do .click() to eventually click it, but i cant even find the element yet)
The desired element is a dynamic element, so invoke click() on it you have to induce WebDriverWait for the element to be clickable and you can use either of the following solutions:
Using CSS_SELECTOR:
element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.hub-content-item[id*='SearchExplorer'][actiontype='Secondary']>span")))
Using XPATH:
element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='hub-content-item' and contains(#id,'SearchExplorer')][#actiontype='Secondary']/span[text()='How to Project Wirelessly in Philly']")))
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

Selenium and iframe in html

Unable to use send_keys() for an iframe. How to select this iframe and which element inside this should be use for send_key()?
and iframe html code
<iframe class="textarea" src="/framework/html/blank.html" style="width: 99%; border-width: 1px; height: 332px;">
#document
<html webdriver="true">
<head>
</head>
<body> … </body>
</html>
</iframe>
How to send the value to description?
One more thing i want to know that this code of frame is not coming when i go for "view page source " in browser?
driver.switch_to.frame(driver.find_element_by_tag_name("iframe")) assuming that driver is a healthy instance of webdriver. To continue with the default content do driver.switch_to.default_content()
EDIT: When you have switched to needed frame, locate your webelement as you always do. I guess (but not sure) in your case this will be a html/body, so
el = driver.find_element_by_xpath('html/body')
should be fine. And perform
el.send_keys('keys_to_send')
EDIT2: Before sending keys you may have to focus on the element (click should do the thing, a child element should appear). Or you can just place the needed text via JS.
driver.execute_script('document.body.innerHTML = "%s"' % text_var)
The Accepted answer works very well for the given question. However I have two reasons for adding one more answer and hope this answer might help someone landing this question with different ask.
Reason 1:
Accepted answer has one way of handling iframes inside a web page. However there are different ways to handle iframes.
By using index position of the frame
By using name of the frame
By using id of the frame
Reason 2:
It uses driver.find_element_by_tag_name("iframe") statement to find iframe element which may not work or return expected iframe web element when there are multiple iframe elements in the same page.
There are many articles out there to explain handling iframes in detail.
http://allselenium.info/handling-iframes-using-selenium-webdriver/
You can switch to the iframe using multiple approaches as per the prevailing condition of the HTML DOM.
If the <iframe> is the only iframe within the DOM Tree you can use the following line of code:
Using TAG_NAME:
driver.switch_to.frame(driver.find_element(By.TAG_NAME, "iframe"))
Locating the <iframe> element with a unique Locator Strategy:
Using css_selector:
driver.switch_to.frame(driver.find_element(By.CSS_SELECTOR, "iframe.textarea[src='/framework/html/blank.html']"))
Using xpath:
driver.switch_to.frame(driver.find_element(By.XPATH, "//iframe[#class='textarea' and #src='/framework/html/blank.html']"))
Ideally to switch to an <iframe> so you have 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 either of the following Locator Strategies:
Using TAG_NAME (only iframe present):
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.TAG_NAME, "iframe"))).click()
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe.textarea[src='/framework/html/blank.html']")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "element_css_selecor"))).send_keys("character_sequence")
Using XPATH:
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[#class='textarea' and #src='/framework/html/blank.html']")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='TlogBtn']/span[#class='mailicn']/img"))).send_keys("character_sequence")
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Reference
You can find a couple of relevant discussions in:
Switch to an iframe through Selenium and python
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element while trying to click Next button with selenium
selenium in python : NoSuchElementException: Message: no such element: Unable to locate element
In order to handle iframes on a web page you need to switch to the iframes first that are present on the page using this command:
driver.switch_to.frame(frame_id)
This tutorial has a working example of handling iframe using selenium with python which will made you able to get through this issue.

Categories

Resources