I have a website having youtube iframe. I want to click the replay button after the video gets over. I switched to youtube iframe and found the play button. But how can I click it after a particular time period(like after the video gets over) using selenium(python). Here the element to be clicked is always available but i need to click it only after a particular time.
driver.switch_to.frame(driver.find_element_by_xpath("//iframe[#id='YTPlayer']"))
driver.implicitly_wait(10000)
driver.find_element_by_css_selector(".ytp-play-button.ytp-button").click()
Tried Explicit wait as well but the conditions dont match.
An implicit wait tells WebDriver to poll the DOM for a certain amount of time when trying to find any element (or elements) not immediately available. The default setting is 0. Once set, the implicit wait is set for the life of the WebDriver object.
This is probably not what you want as your element is available all the time.
Instead you can just run time.sleep() within your code.
Like this:
driver.switch_to.frame(driver.find_element_by_xpath("//iframe[#id='YTPlayer']"))
time.sleep(1)
driver.find_element_by_css_selector(".ytp-play-button.ytp-button").click()
However instead you should try to find a condition that needs to be satisfied and then click the button instead.
Example:
driver.switch_to.frame(driver.find_element_by_xpath("//iframe[#id='YTPlayer']"))
while True:
if your-condition:
driver.find_element_by_css_selector(".ytp-play-button.ytp-button").click()
break
time.sleep(1)
You could also use Explicit Waits as described here: http://selenium-python.readthedocs.io/waits.html
Related
I have this problem where I can't access a button trough it's class name in any way I could think of.
This is the HTML:
<button class="expand-button">
<faceplate-number pretty="" number="18591"><!---->18.591</faceplate-number> weitere Kommentare anzeigen
</button>
I tried to access it using:
driver.find_element(By.CLASS_NAME, "expand-button")
But the error tells me that there was no such element.
I also tried X-Path and Css-Selector which both didn't appear to work.
I would be glad for any help!
Kind Regards and Thanks in advance
Eirik
Possible issue 1
It could be because you check before the element is created in the DOM.
One way to solve this problem is by using the waites option like below
driver.implicitly_wait(10)
driver.get("http://somedomain/url_that_delays_loading")
my_dynamic_element = driver.find_element(By.ID, "myDynamicElement")
You can read more about it here: https://www.selenium.dev/documentation/webdriver/waits/#implicit-wait
Another way is by using the Fluent Wait whhich marks the maximum amount of time for Selenium WebDriver to wait for a certain condition (web element) becomes visible. It also defines how frequently WebDriver will check if the condition appears before throwing the “ElementNotVisibleException”.
#Declare and initialise a fluent wait
FluentWait wait = new FluentWait(driver);
#Specify the timout of the wait
wait.withTimeout(5000, TimeUnit.MILLISECONDS);
#Sepcify polling time
wait.pollingEvery(250, TimeUnit.MILLISECONDS);
#Specify what exceptions to ignore
wait.ignoring(NoSuchElementException.class)
#specify the condition to wait on.
wait.until(ExpectedConditions.element_to_be_selected(your_element_here));
you can also read more about that from the official documentation
https://www.selenium.dev/documentation/webdriver/waits/#fluentwait
Possible issue 2
it is also possible that the element might be partially or completely blocked by an element overlaying it. If that is the case, then you will have to dismiss the overlaying element before you will be able to perform any action on your target
I have built a bot that plays an online roulette with Selenium (Selenium Grid) and Python.
When it comes to clicking on the number I want to bet on, it is extremely slow and does not manage to complete its stake (within the given time range for the bet) across all numbers that make my bet complete.
It seems like slowness may be given from the animation the button does after I click on it.
The code is very simple:
element = WebDriverWait(driver, timeout).until(EC.presence_of_element_located((By.XPATH, path)) # I manage to retrieve the WebElement, this is fast, no problem here
element.click() # this is slow
Here you can find:
how it looks now > https://drive.google.com/file/d/1dEuWTtrXHzRfXXVHhUbdNR8XtgMeWdU-/view?usp=sharing
my target > https://drive.google.com/file/d/1NUbr6rpOGjdMuClD5hby91jPVumqwLC5/view?usp=sharing (here I use the pynput library which is not my target cause I want the script to run on the server using Selenium Grid).
Anyone can help?
I'm not actually sure, is it the same problem or not. In my case, after clicking submit button on login form and redirecting to home page, my script doesn't do anything for around 4 minutes.
I've noticed, that WebElement.click() function ends execution only after page stops loading, but some trackers on site prevent page from complete loading, so I added uBlock extension and got rid of my problem.
I'm trying to implement an explicit wait before giving a click on a checkbox:
WebDriverWait(self.driver, 10).until(EC.element_to_be_clickable((By.XPATH, "pay_type_list_item_id_salary"]")))
self.driver.find_element_by_xpath('//input[#id="pay_type_list_item_id_salary"]').click()
My problem is that my explicit wait keeps sending the error:
not clickable at point (663, 478). Other element would receive the click.
I'm trying to use different kind of explicit waits like visibility_of_element_located or invisibility_of_element_located (using an element from the previous step on my script), but no luck with those options.
If I add a time.sleep(1) between the 2 lines my scripts works but I know it's not the most efficient thing to use time.sleep.
The previous step before this one opens a calendar and I'm not sure if it tries to give the click when the calendar is closing and that's the reason to receive this error.
The error you are getting is indicating that another element is covering the element you are trying to click. If you look at the error message (you really should post the full error message in your question), it will tell you the HTML of the element that is in the way. That will give you a good idea of what element is blocking the click so you can find it and figure out what part of the page it is. Then you can wait for it to get out of the way. From your description, it sounds like you need to add a wait for the calendar to close.
I am writing a script right now to take information from a website and there is a lot of select/option fields. The problem is, currently I am checking to see if the select box is clickable before trying to click the options but this works about 15% of the time. Here is the line that waits for the element to be clickable:
schoolbox = Select(WebDriverWait(driver, 100).until(EC.element_to_be_clickable((By.ID, "clCampusSelectBox"))))
How do I wait for the options below this select element to be clickable?
Thanks
Edit: here are the dropdowns: https://shop.bookstore.ubc.ca/courselistbuilder.aspx
Clickable element has to be visible and enabled. The <option> elements under the <select> are usually not visible, so "is clickable" check will fail. I suggest you wait for the dropdown to be visible and then use select class to select the option
schoolbox = Select(WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "clCampusSelectBox"))))
schoolbox.select_by_value("someValue")
I am writing this to inform you that waiting for select_list and waiting for options are two different thing! Why are you waiting for select_list to be clickable? You need to wait for option,right? I don't know python, I am using WATIR(language is Ruby) where waiting for select_list and then waiting for option will automatically happen, you don't have write anything
This simple code is enough
b.select_list(:id,'q').select 'hi'
It will automatically wait for select list to be present and then it will wait for option to be present, you don't have to do anything deliberately.
But if I want to write the code to wait for select_list, then I will write
b.select_list(:id,'q').wait_until_present.select 'hi'
If I want to write the code to wait for option in the select_list then I will write
b.select_list(:id,'q').option(:text,'hi').wait_until_present.select
If I want to wait for both, then I will write
b.select_list(:id,'q').wait_until_present.option(:text,'hi').wait_until_present.select
but these are not necessary in WATIR because it automatically waits for everything.
So all you need to know is whether to wait for select_list or to wait for option because in certain condition your select list option will be populated according to some condition.
I am using the python unit testing library (unittest) with selenium webdriver. I am trying to find an element by it's name. About half of the time, the tests throw a NoSuchElementException and the other time it does not throw the exception.
I was wondering if it had to do with the selenium webdriver not waiting long enough for the page to load.
driver = webdriver.WhatEverBrowser()
driver.implicitly_wait(60) # This line will cause it to search for 60 seconds
it only needs to be inserted in your code once ( i usually do it right after creating webdriver object)
for example if your page for some reason takes 30 seconds to load ( buy a new server), and the element is one of the last things to show up on the page, it pretty much just keeps checking over and over and over again if the element is there for 60 seconds, THEN if it doesnt find it, it throws the exception.
also make sure your scope is correct, ie: if you are focused on a frame, and the element you are looking for is NOT in that frame, it will NOT find it.
I see that too. What I do is just wait it out...
you could try:
while True:
try:
x = driver.find_by_name('some_name')
break
except NoSuchElementException:
time.sleep(1)
# possibly use driver.get() again if needed
Also, try updating your selenium to the newest version with pip install --update selenium
I put my money on frame as I had similar issue before :)
Check your html again and check if you are dealing with frame. If it is then switching to correct frame will be able to locate the element.
Python
driver.switch_to_frame("frameName")
Then search for element.
If not, try put wait time as others suggested.
One way to handle waiting for an element to appear is like this:
import selenium.webdriver.support.ui as ui
wait = ui.WebDriverWait(driver,10)
wait.until(lambda driver: driver.find_by_name('some_name') )
elem = driver.find_by_name('some_name')
You are correct that the webdriver is not waiting for the page to load, there is no built-in default wait for driver.get().
To resolve this query you have to define explicit wait. so that till the time when page is loading it will not search any WebElement.
below url help on this.
http://docs.seleniumhq.org/docs/04_webdriver_advanced.jsp
You need to have a waitUntil (your element loads). If you are sure that your element will eventually appear on the page, this will ensure that what ever validations will only occur after your expected element is loaded.
I feel it might be synchronisation issue (i.e webdriver speed and application speed is mismatch )
Use Implicit wait:
driver.manage.timeouts.implicitlyWait(9000 TIMEUNITS.miliseconds)
Reference