The page is not loaded, the script does not wait alone the page has been downloaded and rendered, that is to say the DOM is probably not ready
For this you can apply a reasonable waiting time of 10 to 30 seconds limit, to wait for the DOM process, an example form implicit:
browser = webdriver.Chrome(r'')
browser.implicitly_wait(10)
If ten seconds isn’t enough use 20:
browser.implicitly_wait(20)
If you don’t use 30:
browser.implicitly_wait(30)
Or use the shape explicit, to add this at the top of the script:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
And change:
al=browser.find_element_by_link_text('ALLOW')
By (using Xpath):
al = WebDriverWait(browser, 10).until(
EC.presence_of_element_located((By.XPATH, '//*[text() = "ALLOW"]'))
)
If ten seconds isn’t enough use 20:
WebDriverWait(browser, 20)
If you don’t use 30:
WebDriverWait(browser, 30)
You should only use more than this if you are sure the requested page is slow.
Checking if the element is clickable
Note that even if the element exists and is ready it may be that when using the click()
it is "non-clickable" and will cause some problems like:
ElementNotVisibleException
ElementNotSelectableException
Depending on the situation, as hidden, then on buttons and links instead of EC.presence_of_element_located
use EC.element_to_be_clickable
, thus:
al = WebDriverWait(browser, 10).until(
EC.element_to_be_clickable((By.XPATH, '//*[text() != "ALLOW"]'))
)
Note that for other types of elements you can apply other conditions (EC
):
EC.title_is
EC.title_contains
EC.visibility_of_element_located
EC.visibility_of
EC.presence_of_all_elements_located
EC.text_to_be_present_in_element
EC.text_to_be_present_in_element_value
EC.frame_to_be_available_and_switch_to_it
EC.invisibility_of_element_located
EC.staleness_of
EC.element_to_be_selected
EC.element_located_to_be_selected
EC.element_selection_state_to_be
EC.element_located_selection_state_to_be
EC.alert_is_present
Do not use sleep()
It’s not that it shouldn’t, unless it’s in the interest of the actual script to use, but for DOM within Selenium the ideal is to use the
WebDriverWait
, this because it looks for the element at all times until the limit (10, 20, 30, etc.) ends, ie if find before the time limit it will not need to continue, it will process before and will not get stuck until the time runs out
Error:Attributeerror: module 'Selenium.webdriver.support.expected_conditions' has no attribute 'find_element_by_link_text'
– Pakito
@Pakito which version of Selenium? ps: I used this same code here and it worked, if not use implicity_wait ... DON’T USE THE
sleep()
, he does not "check" if the DOM is ready, will lock everything, theimplicitly_wait
, The GREAT advantage of implicitly_wait and Webdriverwait is that they search in the DOM until the time runs out, or if the element is found before the time limit it will proceed without having to finish the time, unlike the Sleep that just locks everything and will be forced to wait to finish all the time.– Guilherme Nascimento
Gave another error:EC.presence_of_element_located((by.XPATH, '//*[text() != "ALLOW"]')) Nameerror: name 'by' is not defined
– Pakito
@Pakito import the
from selenium.webdriver.common.by import By
, sorry, there are many classes I often forget to mention: from Selenium.webdriver.common.by import By. I edited the answer– Guilherme Nascimento
do not need al.click() ? in the 2 option?
– Pakito
Dear @Pakito never said this, I solved the part that was in your code, the part of "fetch the element", what you will do with it, click, remove, move, is of your interest... ps: the
element_to_be_clickable
"check if it is clickable", as described in the highlighted, do not click, just check if it is "possible", then you run click after what you want, in the examples solved the part with problem.– Guilherme Nascimento
Only in the problem was the variable al.click()
– Pakito
@Pakito why? Not correct
al=
here:al = WebDriverWait(browser, 10).until(...
?– Guilherme Nascimento
No and that For when this variable also had the aim to click so I thought it was clear!
– Pakito
But Being Able to Help?
– Pakito
@Pakito didn’t understand, where exactly are you failing? Did you do this
al = WebDriverWait(browser, 10).until(
 EC.element_to_be_clickable((By.XPATH, '//*[text() != "ALLOW"]'))
) al.click()
?– Guilherme Nascimento
In the Code I Updated I just wanted to get Clickar in this Box.
– Pakito