I'm a noob and trying to automate some online form filling in a certain site. My problem is that some buttons need some time before clicking them, otherwise they don't work (but no error!, execution continues).
My only solution so far is to add a time.sleep(6) before these buttons but this is not ideal.
I am trying to find a better solution.
So far, I have this function:
def Send_Click_dk(bywhat,what):
WebDriverWait(browser, 10).until(EC.presence_of_element_located((bywhat,what)))
WebDriverWait(browser, 10).until(EC.visibility_of(browser.find_element(bywhat, what)))
WebDriverWait(browser, 10).until(EC.element_to_be_clickable(browser.find_element(bywhat, what)))
browser.find_element(bywhat, what).click()
Send_Click_dk(By.NAME, "mainpanel_parentSection_1b0a0b")
First of all, is this a good approach? Am I misunderstanding something?
Secondly, if this is the right approach, what else could I check before clicking the button? So far, all of these checks pass instantly and the .click() is executed but doesn't produce the expected result. Only by adding time.sleep(6) the clicking works as intended.
This is a snapshot of that particular part of the page, I'm having trouble copying the raw text.
The first marked button reveals the second marked button. But if without the time.sleep(x) it just stays closed without revealing the second one.
Many thanks in advance for any help! Cheers!
You definitely can reduce all your code to a single line of
def Send_Click_dk(bywhat,what):
WebDriverWait(browser, 10).until(EC.element_to_be_clickable(browser.find_element(bywhat, what))).click()
Send_Click_dk(By.NAME, "mainpanel_parentSection_1b0a0b")
visibility_of expected condition includes presence_of_element_located since element can't be visible without being present.
element_to_be_clickable internally includes visibility_of.
Also WebDriverWait(browser, 10).until(EC.element_to_be_clickable(browser.find_element(bywhat, what))) returns web element object, so you can click it directly.
Also, make sure the mainpanel_parentSection_1b0a0b name attribute is a fixed value. 1b0a0b suffix seems to be dynamically generated
Related
I have a selenium script that runs a loop on a process that prints text into my python IDLE to get a list of data, which I then copy and paste to excel - which is great. But not optimal.
I am currently using sleep at the start of the loop to give me time to change parameters on my trading view strategy tester, which gives me a different result to be printed as intended. However, I would like more or less time on most occasions. Waiting for the path to change does not work as the path never changes, it just gets looped again with a different text output based on the changes I would have made manually on the strategy settings.
Also worth noting that I am using firefox geckobrowser as opposed to chrome and that the purpose of the script is to automate a tedious manual task of data collection.
Is it at all possible to create a pop-up button or something of the like via selenium that says "Next" for example, that I can click and let the script know its okay for the loop to continue? Can I simply replace sleep with click "Next" or something of the like for example?
for i in range(20):
time.sleep(10)
netProfit = driver.find_element("xpath", '/html/body/div[2]/div[7]/div[2]/div[4]/div/div[2]/div/div[1]/div[1]/div[2]/div[2]')
numberTrades = driver.find_element("xpath", '/html/body/div[2]/div[7]/div[2]/div[4]/div/div[2]/div/div[1]/div[2]/div[2]')
winRate = driver.find_element("xpath", '/html/body/div[2]/div[7]/div[2]/div[4]/div/div[2]/div/div[1]/div[3]/div[2]')
print(netProfit.text, numberTrades.text, winRate.text)
This works for now, but it's a pain waiting for timer on occasions I don't need it and even more of a pain on occasions when it's not enough time.
I am expecting something like this to replace time.sleep(10)
WebDriverWait(driver, 180).until("Next" button is clicked)
Ideally I would like a solution that can be done in selenium as my experience is limited, but any workarounds would be appreciated all the same.
I run a multithread python selenium script which gives me unexpected behavior which I can not understand. So after opening a new browser I try to clear the cache with below code ;
driver.get('chrome://settings/clearBrowserData')
WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, '//settings-ui')))
driver.find_element_by_xpath('//settings-ui').send_keys(Keys.ENTER)
90 out of 100 times this works but sometimes it throws me this error :
element not interactable
To my understanding somehow the page is not loaded fully and selenium is too "fast".
However I do wait until the element is visible which would eliminate this plus to my understanding the driver.get also waits until the "full get" is returned and finished.
Can someone explain me why this behavior occurs ?
Sub question would be is my understanding right driver.get(page) waits for full page loading done ?
The ElementNotInteractableException exception can occur for a few reasons:
The element that you want to interact with is disabled.
There's an overlay element covering the one you want to interact with, such as a loading spinner.
If it's 1, use EC.element_to_be_clickable instead of EC.visibility_of_element_located.
If it's 2, you'll need to either wait for the overlay element to go away on it's own. Or, perform an action to make the overlay element go away.
I am a beginner in selenium and having a tough time understanding one of the errors appearing while using selenium chromedriver in python.
So, I am trying to click an element inside an svg tag by using css_selector. But I am getting ElementClickInterceptedException with the error (... is not clickable at point (1281, 60). Other element would receive the click:...). However, if I am putting time.sleep(5) before clicking the element, then I am able to click it. Why is it happening?
My first guess was maybe the element is not becoming visible or is inside an invisible box and I have to wait. Hence I tried to handle it with the explicit wait. But both cases timed out. So I assumed, it was not due to that. But then it is difficult for me to guess the reason, as time.sleep(5) is working.
Thank you in advance.
I have a Python/Selenium script working through a page, and in an effort not to spam the server I have half second sleeps between interactions with page elements. I've noticed an issue where the script "lost track" of items in my list, and just recently discovered that it seems to be due to the page auto-updating/resetting during the script's run. The id's seem to be dynamically generated, so the refresh usually alters some of the id's, and the script crashes.
When I first encountered the issue, I just put a try-catch on it, skipping elements it had lost track of and logging an error, as I didn't have any real information on the issue and it was infrequent.
Giving it some more thought, and watching the script in action for a while, I noticed a slight refresh and the page re-ordering some elements.
The best idea I've come up with is below, where I reload the page entirely and refresh the list MID-LOOP and starting over. This is clearly a wrong way to address this. What is a better option?
try:
browser.execute_script("arguments[0].click();", button)
except link_lost:
print('Lost track of something...')
browser.refresh() # Page glitch fix. Refresh, relocate buttons, start over.
browser.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(5) # could be optimized by keeping track of which question we're on and starting from there
target_buttons = browser.find_elements_by_css_selector('[aria-label=target]')
you can do this easily using selenium functions:
find parrent element of list and then go to the first element that want to click
using xpath find element that you want to click, save it's as variable
example:
add_button = driver.find_elements_by_xpath('//button[contains(text(), "Dodaj")]')
contact_field = add_button[0].find_elements_by_xpath('.//parent::*/parent::*/parent::*/parent::*/parent::*/parent::*/parent::*/parent::*/parent::*')
name_of_contact = contact_field[0].find_element_by_xpath('.//div/div/div/div/div/a')
for example, name_of_contact is your variable and contact_field is parrent element like list or window.
now just use contact_field[0].click() and no matter what happen it will be always first element from that list.
above you see it from two sides, add_button is the element on page, using it I find a parrent element of contact_field where were all info, then I find appropriate descendant (name_of_contact)
Im having this code, if there's the time.sleep(2) it clicks and if it's not there it doesnt click on the elements. It doesn't even wait a second
time.sleep(2)
WebDriverWait(self.broswer, 30).until(EC.element_to_be_clickable((By.CLASS_NAME, 'something')))
self.browser.find_element_by_class_name('something').click()
I tried to use the following instead
self.browser.implicitly_wait(2)
but it doesnt wait and I cant use time.sleep()
Time.Sleep() is counting time in milliseconds, therefore Time.Sleep(2) is 2 milliseconds, maybe if you try,
Time.Sleep(2000);
it may work for you.
time.sleep() and WebDriverWait() are different methods of waiting. It's best practice to avoid use of time.sleep() and prefer WebDriverWait.
In another comment you said that you don't even want to wait, you just want to click the button. If that's the case, you should be able to just use this
self.browser.find_element_by_class_name('something').click()
but you said that you get an error. What is the error that you get if you only run that one line?
Side note...
WebDriverWait.until() should return the WebElement specified so if you decide you want to keep the wait, you can do this
WebDriverWait(self.broswer, 30).until(EC.element_to_be_clickable((By.CLASS_NAME, 'something'))).click()
I come from a Java background and don't know python so I may have some typos here and there... but this should get you headed in the right
what is the problem with time.sleep()
If you don't want to user time.sleep() and still if you want to force web driver to wait for specific time then you can give condition also.
you can go through with below url for java
http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html#invisibilityOfElementLocated-org.openqa.selenium.By-
1)
Use the time.sleep() (which is in seconds "Suspend execution of the current thread for the given number of seconds")only when you really need it.
2)
Learn, deeply, the differences between IMPLICIT WAIT and EXPLICIT WAIT
Sometimes,I had the need to force the "physical" hard-ware wait, the I used the time.sleep(), but I really suggest you to comprehend the difference between the two waiting method which selenium provides you.
#Dor Alt: Remember that the (from documentation) "An explicit waits is code you define to wait for a certain condition to occur before proceeding further in the code." If you get any kind of error, please write it here and tell us which browser you're using for your test, because different browsers have (very, very and very) different behaviours! :)
I mean, if you are using Chrome and IE (as far as I know) if the webdriver doesn't have the visualization of the element you want to click, it does not click! In this case, for example, you should move/scroll the page with a script like this: driver.execute_script('window.scrollTo(0, {0})'.format(element.location['y']))