I'm trying to switch the Selenium 'focus' to the contents inside of an iframe that's inside of another iframe. My selenium test below seems to work so far. However, there is another iframe within that iframe that I want to get- but I'm not sure now.
Here is the markup (second iframe highlighted):
This is my test so far (which works- just not sure how to get the second iframe within the first iframe):
import unittest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec
from .functional_test import FunctionalTest
class MyTest(FunctionalTest):
URL = '/datastory/my-datastory/'
#classmethod
def setUpClass(cls):
"""Set up method."""
super().setUpClass()
cls.URL = cls.format_url(cls.URL)
cls.login_user(cls)
def test_iframe(self):
container = self.browser.find_element_by_id('visual-31')
carousel = container.find_element_by_css_selector('.col-sm-12:nth-child(2) div.visual #classics-50-carousel')
wait = WebDriverWait(self.browser, 60)
wait.until(ec.visibility_of(carousel))
page_source = carousel.get_attribute("src");
self.assertEqual(
page_source,
'https://observablehq.com/embed/#ddsg/paramount-databyte-visuals?cells=classics50yrs'
)
# switch Selenium focus to the iframe
iframe = self.browser.switch_to.frame(carousel);
#NOW HOW DO I GET THE OTHER IFRAME??
# switch back
self.browser.switch_to.default_content()
To switch within nested <iframe> elements so you have to:
Induce WebDriverWait for the parent frame to be available and switch to it.
Induce WebDriverWait for the child frame to be available and switch to it.
Then driver.find_element()
You can use either of the following Locator Strategies:
Using CSS_SELECTOR:
driver.get('https://xyz/datastory/my-datastory/')
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe.content[src='https://observablehq.com/embed/#ddsg/paramount-databyte-visuals?cells=classics50yrs']")))
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe.content[src*='observableusercontent']")))
element = driver.find_element(By.ID, "id")
Using XPATH:
driver.get('https://xyz/datastory/my-datastory/')
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[#class='content' and #src='https://observablehq.com/embed/#ddsg/paramount-databyte-visuals?cells=classics50yrs']")))
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[starts-with(#src, 'observableusercontent')]")))
element = driver.find_element(By.ID, "id")
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
Related
I want to go from this page to this https://resultats.ffbb.com/organisation/b5e6211d5970.html to this page https://resultats.ffbb.com/championnat/b5e6211f621a.html?r=200000002810394&d=200000002911791&p=2 by clicking on 'Régional féminin U15'.
I have tried many solutions but the best I had, is not working systematically.
Please coul you help me?
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
import selenium.webdriver.support.ui as ui
import time
driver = webdriver.Firefox()
driver.get("https://resultats.ffbb.com/organisation/b5e6211d5970.html")
driver.switch_to.frame("idIframeChampionnat")
#sign_in = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, '/html/body/pre/span[93]'))).click();
button = driver.find_element_by_partial_link_text(u"minin U15")
button.click()```
To click() on the link with text as Régional féminin U15 as the elements are within 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 CSS_SELECTOR:
driver.get("https://resultats.ffbb.com/organisation/b5e6211d5970.html")
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe#idIframeChampionnat")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.LINK_TEXT, "Régional féminin U15"))).click()
Using XPATH:
driver.get("https://resultats.ffbb.com/organisation/b5e6211d5970.html")
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[#id='idIframeChampionnat']")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.LINK_TEXT, "Régional féminin U15"))).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
Browser Snapshot:
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
Try
driver.switch_to.frame("idIframeChampionnat")
button = driver.find_element_by_xpath("//a[contains(text(), 'minin U15')]")
button.click()
or
driver.switch_to.frame("idIframeChampionnat")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[contains(text(), 'minin U15')]"))).click()
This is my code example in groovy (sorry, haven't python env), pretty similar to yours, and it works perfectly 20 times in a loop even without timeouts.
#Test(invocationCount = 20)
void test() {
driver.get('https://resultats.ffbb.com/organisation/b5e6211d5970.html')
driver.switchTo().frame(
driver.findElement(By.xpath("//iframe[#id='idIframeChampionnat']"))
)
driver.findElement(By.xpath("//a[contains(text(), 'minin U15')]")).click()
driver.switchTo().defaultContent()
assert driver.getCurrentUrl() ==
'https://resultats.ffbb.com/championnat/b5e6211f621a.html?r=200000002810394&d=200000002911791&p=2'
}
So, I have no ideas. Maybe just add driver.switch_to.default_content() after click?
im new to python and recently got into selenium , i made small projects for linkedin or twitter with it from a tutorial but now i wanted to do smth for my work(finance) and my problem is:
On this website: https://mfinante.gov.ro/domenii/informatii-contribuabili/persoane-juridice/info-pj-selectie-dupa-cui
When i try to find a element by any selector(name xpath css selectors etc) it tells me there is no such element
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import time
from selenium.common.exceptions import NoSuchElementException
URL = 'https://mfinante.gov.ro/domenii/informatii-contribuabili/persoane-juridice/info-pj-selectie-dupa-cui'
s = Service('My chromedriver path')
driver = webdriver.Chrome(service = s)
driver.get(URL)
driver.maximize_window()
time.sleep(3)
cui_entry = driver.find_element(By.CSS_SELECTOR,'.col-sm-4 p input')
cui_entry.send_keys('23484xxx')
What i want it to do is to write this code where it says Introduceti codul unic de identificare (numeric): but it seems like im doing something wrong
To send a character sequence to the Enter the unique identification code (numeric) field as the elements are within 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 CSS_SELECTOR:
driver.get("https://mfinante.gov.ro/domenii/informatii-contribuabili/persoane-juridice/info-pj-selectie-dupa-cui")
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe#_com_liferay_iframe_web_portlet_IFramePortlet_INSTANCE_AAFALwmoH3eD_iframe")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[name='cod']"))).send_keys("23484")
Using XPATH:
driver.get("https://mfinante.gov.ro/domenii/informatii-contribuabili/persoane-juridice/info-pj-selectie-dupa-cui")
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[#id='_com_liferay_iframe_web_portlet_IFramePortlet_INSTANCE_AAFALwmoH3eD_iframe']")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#name='cod']"))).send_keys("23484")
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
Browser Snapshot:
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
I have been trying to webscrape some information from a webside with Selenium in Python. I load the webside, but I can't accept the cookies, which is necessary to continue. I have tried to use explicitly wait as I suspected that the problem was that the webside loaded before the "accept" bottom becomes clickable.
My code is:
import os
import until as until
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
os.environ['PATH'] += r"C:\Users\BackUp HDL\AppData\Local\Programs"
driver = webdriver.Chrome()
driver.get("https://watchmedier.dk/latest/filtered? sitesFilter=policywatch.dk&sitesFilter=shippingwatch.dk&sitesFilter=mobilitywatch.dk&sitesFilter=energiwatch.dk&sitesFilter=finanswatch.dk&sitesFilter=ejendomswatch.dk&sitesFilter=mediawatch.dk&sitesFilter=agriwatch.dk&sitesFilter=fodevarewatch.dk&sitesFilter=medwatch.dk&sitesFilter=kapwatch.dk&sitesFilter=itwatch.dk&sitesFilter=ctwatch.dk&sitesFilter=watchmedier.dk&sitesFilter=advokatwatch.dk")
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="notice"]/div[3]/button[2]')))
driver.find_element_by_xpath('//*[#id="notice"]/div[3]/button[2]').click()
Whenever I try to run the code I get an error. Can someone please help me out?
The element Accepter is within 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 CSS_SELECTOR:
driver.get("https://watchmedier.dk/latest/filtered? sitesFilter=policywatch.dk&sitesFilter=shippingwatch.dk&sitesFilter=mobilitywatch.dk&sitesFilter=energiwatch.dk&sitesFilter=finanswatch.dk&sitesFilter=ejendomswatch.dk&sitesFilter=mediawatch.dk&sitesFilter=agriwatch.dk&sitesFilter=fodevarewatch.dk&sitesFilter=medwatch.dk&sitesFilter=kapwatch.dk&sitesFilter=itwatch.dk&sitesFilter=ctwatch.dk&sitesFilter=watchmedier.dk&sitesFilter=advokatwatch.dk")
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe[title='SP Consent Message']")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[title='Accepter']"))).click()
Using XPATH:
driver.get("https://watchmedier.dk/latest/filtered? sitesFilter=policywatch.dk&sitesFilter=shippingwatch.dk&sitesFilter=mobilitywatch.dk&sitesFilter=energiwatch.dk&sitesFilter=finanswatch.dk&sitesFilter=ejendomswatch.dk&sitesFilter=mediawatch.dk&sitesFilter=agriwatch.dk&sitesFilter=fodevarewatch.dk&sitesFilter=medwatch.dk&sitesFilter=kapwatch.dk&sitesFilter=itwatch.dk&sitesFilter=ctwatch.dk&sitesFilter=watchmedier.dk&sitesFilter=advokatwatch.dk")
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[#title='SP Consent Message']")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#title='Accepter']"))).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
Browser Snapshot:
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
I want to click the "Akkoord" button but I am unable to do that. I already tried different methods but they are not working. Any help will be appreciated.
one of the codes I tried.
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
import time
driver = webdriver.Chrome(ChromeDriverManager().install())
driver.get('https://www.demorgen.be/nieuws')
time.sleep(20)
driver.find_elements_by_class_name('message-component message-button no-children pg-accept-button')[0].click()
The element Akkoord is within 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 CSS_SELECTOR:
driver.get("https://www.demorgen.be/nieuws")
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe[id^='sp_message_iframe']")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[aria-label='Akkoord']"))).click()
Using XPATH:
driver.get("https://www.demorgen.be/nieuws")
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[starts-with(#id, 'sp_message_iframe')]")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#aria-label='Akkoord']"))).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
Browser Snapshot:
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
use xpath or css
css :
[class="message-component message-button no-children pg-accept-button"]
driver.find_elements_by_css_selector('[class="message-component message-button no-children pg-accept-button"]')[0].click()
xpath:
//*[#class="message-component message-button no-children pg-accept-button"]
driver.find_elements_by_xpath('//*[#class="message-component message-button no-children pg-accept-button"]')[0].click()
find_elements_by_class_name expects single class name as argument thats why its not working as space in class indicates multiple classes.
THe find by class actually uses css under the hood. So if you want to find element having multiple class . You can replace space with '.' (THis works only in python)
driver.find_elements_by_class_name('message-component.message-button.no-children.pg-accept-button')[0].click()
Also
The element is inside iframe
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
frame = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR,
"#sp_message_container_404503 iframe")))
driver.switch_to_frame(frame)
driver.find_element_by_css_selector(
'[class="message-component message-button no-children pg-accept-button"]').click()
I am trying to scrape some data from an iframe located within a webpage. The URL of the webpage is https://www.nissanoflithiasprings.com/schedule-service. I am trying to access the button shown in the image below:
When I right-click on the button (located inside the iframe) to view the source code, I am able to see the HTML id and name (see screenshot below):
The "id" for the button is "new_customer_button". However, when I use selenium webdriver's driver.find_element_by_id("new_customer_button") to access the button, the code is not able to locate the button inside the iframe and throws the following error:
NoSuchElementException: no such element: Unable to locate element: {"method":"id","selector":"new_customer_button"}
Below is the code that I have tried so far:
from selenium import webdriver
chrome_path = r"C:\Users\gh455\Downloads\chromedriver_win32\chromedriver.exe"
driver = webdriver.Chrome(chrome_path)
driver.get("https://www.nissanoflithiasprings.com/schedule-service")
dest_iframe = driver.find_elements_by_tag_name('iframe')[0]
driver.switch_to.frame(dest_iframe)
driver.find_element_by_id("new_customer_button")
Not sure why this is happening. Any help will be appreciated. Thanks!
The element is inside multiple <iframe> tags, you need to switch to them one by one. You should also maximize the window and use explicit wait as it take some time to load
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
chrome_path = r"C:\Users\gh455\Downloads\chromedriver_win32\chromedriver.exe"
driver = webdriver.Chrome(chrome_path)
driver.maximize_window()
driver.get("https://www.nissanoflithiasprings.com/schedule-service")
wait = WebDriverWait(driver, 10)
# first frame - by css selector
wait.until(ec.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, '[src^="https://consumer.xtime.com"]')))
# second frame - by ID
wait.until(ec.frame_to_be_available_and_switch_to_it('xt01'))
driver.find_element_by_id("new_customer_button")
To click() on the element with text as Make · Year · Model as the the desired element is within an nested <iframe>s so you have to:
Induce WebDriverWait for the desired parent frame to be available and switch to it.
Induce WebDriverWait for the desired child frame to be available and switch to it.
Induce WebDriverWait for the desired element_to_be_clickable().
You can use the following solution:
Code Block:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument("start-maximized")
chrome_options.add_argument('disable-infobars')
driver = webdriver.Chrome(options=chrome_options, executable_path=r'C:\WebDrivers\chromedriver.exe')
driver.get("https://www.nissanoflithiasprings.com/schedule-service")
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe[src*='com/scheduling']")))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe[src*='consumerportal']")))
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.button.button--action.btn.btn-secondary#new_customer_button"))).click()
Browser Snapshot:
Here you can find a relevant discussion on Ways to deal with #document under iframe