Element is found but not clickable - python

I'm trying to find an element by it's id, click on it and download a file.
driver.get(url);
driver.implicitly_wait(60);
time.sleep(3)
element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.ID, "ContentPlaceHolder1_a1")))
href = element.get_attribute('href')
value = href.split('/')[-1]
print(value);
element.click(); # Error
Error
element click intercepted: Element is not clickable at point (110, 1003)
I've tried Xpath, and CSS path too. All give the same error. If I check for the visibility then it times out. But I can manually see that the element is visible
element = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, "//a[contains(text(), 'text of the link')]")))
At last, I tried this code.
element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.ID, "ContentPlaceHolder1_a1")))
ActionChains(driver).move_to_element(element).click().perform()
But it gives error
selenium.common.exceptions.MoveTargetOutOfBoundsException: Message: move target out of bounds

While identified the element, page is still loading, may be the reason it is clicking on somewhere else.
Scroll down to the element and then wait for 1 to 2 seconds and then click.
It is working perfectly for me.
element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.ID, "ContentPlaceHolder1_a1")))
element.location_once_scrolled_into_view #scroll down to element
time.sleep(2) # wait for 2 seconds , 1 sec working as well
element.click()

Related

Scroll to a button with Selenium Python

I'm working on a webscraping script for a school project. I have to scroll down to a button to click, but I can't make it work.
I tried the following code:
driver.get('https://www.goodreads.com/book/show/28187.The_Lightning_Thief');
button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '/html/body/div[3]/div/div[1]/div/div/button')))
button.click()
time.sleep(5)
element = driver.find_element(By.CLASS_NAME,"Button Button--transparent Button--small")
actions = ActionChains(driver)
actions.move_to_element(element).perform()
button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '''//*[#id="ReviewsSection"]/div[5]/div/div[4]/a''')))
button.click()
I recieved the following error:
Message: no such element: Unable to locate element: {"method":"css selector","selector":".Button Button--transparent Button--small"}
I also tried this, but it didn't work either:
driver.execute_script("arguments[0].scrollIntoView();", element)
When you scroll down on this page it will load in more reviews, so I guess that the button in the bottom I want to click don't load in, so I also tried to scroll down a few times and then try to scroll to the element, but it didn't work.
Can someone please help out?
EDITED:
I also tried this code:
driver = webdriver.Chrome()
driver.get('https://www.goodreads.com/book/show/13335037-divergent');
button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '/html/body/div[3]/div/div[1]/div/div/button')))
button.click()
time.sleep(3)
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(3)
element = driver.find_element(By.CSS_SELECTOR, "div.Divider.Divider--contents.Divider--largeMargin")
driver.execute_script("arguments[0].scrollIntoView();", element)
button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '''//*[#id="ReviewsSection"]/div[5]/div/div[4]/a''')))
button.click()
This will scroll down to the bottom once end let the remaining reviews load in, then get the element and scroll again. But it's not scrolling down enough so the See all reviews and ratings won't be in view and can't be clicked.
Your selector is invalid since you're trying to pass multiple class names to search by class. You need to pass single #class only or to use another locator type, e.g.
element = driver.find_element(By.CSS_SELECTOR, ".Button.Button--transparent.Button--small")
P.S. Note that there are 4 elements with the same set of class names ("Button Button--transparent Button--small"), so search by class names is not a good option in this case
element = driver.find_element(By.XPATH, '//a[.="See all reviews and ratings"]')

Selenium EC.element_to_be_clickable still returns stale element error

I am not sure what is wrong with this. Am I using EC.element_to_be_clickable() right? I am getting the error message: "selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document". I am pretty sure the XPATH is valid and have even tried with another that designates the same element.
My code:
driver.get("https://browzine.com/libraries/1374/subjects")
parent_url = "https://browzine.com/libraries/1374/subjects"
wait = WebDriverWait(driver, 10)
subjects_avail = driver.find_elements(By.XPATH, "//span[#class='subjects-list-subject-name']")
subjects = 0
for sub in subjects_avail:
WebDriverWait(driver, 5).until(EC.element_to_be_clickable(
(By.XPATH, "//span[#class='subjects-list-subject-name']")))
ActionChains(driver).move_to_element(sub).click(sub).perform()
subjects = +1
driver.get(parent_url)
Each time you clicking the sub element the driver is navigating to the new page.
Then you are opening the main page again with
driver.get(parent_url)
But all the web elements in subjects_avail list became Stale since driver already left the original main page.
To make your code working you have to get the subjects_avail list again each time you getting back to the main page and then select the correct sub title element.
Something like this:
url = "https://browzine.com/libraries/1374/subjects"
subj_list_xpath = "//span[#class='subjects-list-subject-name']"
driver.get(url)
wait = WebDriverWait(driver, 10)
subjects_avail = driver.find_elements(By.XPATH, subj_list_xpath)
for i in range(len(subjects_avail)):
WebDriverWait(driver, 5).until(EC.visibility_of_element_located((By.XPATH, subj_list_xpath)))
subjects_avail = driver.find_elements(By.XPATH, subj_list_xpath)
ActionChains(driver).move_to_element(subjects_avail[i]).click(subjects_avail[i]).perform()
driver.get(url)

PYTHON - StaleElementReferenceException for enabled element

I am trying to click on the "Next page" in Python-Selenium. The element and its path are seen, the buttom is being clicked but after clicking an error is shown:
"StaleElementReferenceException:stale element reference: element is not attached to the page document"
My code so far:
element = WebDriverWait(driver, 20).until(EC.presence_of_element_located(\
(By.XPATH, butn)))
print (element.is_enabled())
while True and element.is_enabled()==True:
driver.find_element_by_xpath(butn).click()
The error is one element.is_enabled()==True after clicking
Can someone help?
When you search elements in Selenium then it doesn't keep full objects but only references to objects in DOM in browser. And when you click then browser creates new DOM and old references are incorrect and you have to find elements again.
Something like this
# find first time
element = WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, butn)))
print(element.is_enabled())
while element.is_enabled():
driver.find_element_by_xpath(butn).click()
# find again after changes in DOM
element = WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, butn)))
print(element.is_enabled())

Selenium: element is not clickable because an other element obscures it

I've been searching around the site but can not seem to find a fix that works for me. I am trying to click a button that should load more reviews.
driver.get("https://www.mediamarkt.nl/nl/product/_philips-essential-airfryer-xl-hd9260-90-1653991.html")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".bv-content-btn-pages-load-more"))).click()
Is the code I am using. This results in an error:
selenium.common.exceptions.ElementClickInterceptedException: Message: Element <button class="bv-content-btn bv-content-btn-pages bv-content-btn-pages-load-more bv-focusable" type="button"> is not clickable at point (674,670) because another element <div class="gdpr-cookie-layer gdpr-cookie-layer--show"> obscures it
I've tried getting the element and then clicking it:
element = driver.find_element_by_class_name('bv-content-btn-pages-load-more')
driver.execute_script("arguments[0].click();", element)
I also tried doing it using an action chain:
element = driver.find_element_by_class_name('bv-content-btn-pages-load-more')
ActionChains(driver).move_to_element(element).click().perform()
What is the actual issue here and how do I fix it?
WebDriverWait(driver, 20).until(EC.element_to_be_clickable(
(By.CSS_SELECTOR, '[class="gdpr-cookie-layer__btn gdpr-cookie-layer__btn--submit gdpr-cookie-layer__btn--submit--all"]'))).click()
WebDriverWait(driver, 20).until(EC.element_to_be_clickable(
(By.CSS_SELECTOR, ".bv-content-btn-pages-load-more"))).click()
you have to first close the accept cookie dialogue , else selenium cannot click the load more element as the accept_cookie screen is in forground

Unable to click on element even after finding it- Python seleneium

I have been pained by a load more button for a while. I'm looking to create a loop where I click "load more" on the skills section of Linkedin pages. However, this button is just not consistently being clicked.
I was under the impression that the issue was that the element was not visible on the page. So, I have a segmented scroll, which continues moving down the page until the element is found. But what's baffling is that even though the page is now moving to the right place, the element is not being clicked. No error is being thrown.
I've tried nearly every version of the element location (xpath, class name, css selector, full xpath). Why would the button not be clicked, if it is visible on the page?
Relevant Code:
##log into Linkedin
linkedin_urls=['https://www.linkedin.com/in/julie-migliacci-revent/']
ChromeOptions = webdriver.ChromeOptions()
driver = webdriver.Chrome('C:\\Users\\Root\\Downloads\\chromedriver.exe')
driver.get('https://www.linkedin.com/login?fromSignIn=true&trk=guest_homepage-basic_nav-header-signin')
driver.maximize_window()
WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.NAME, "session_key"))).send_keys("EMAIL")
WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.NAME, "session_password"))).send_keys("PASSWORD")
WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, "//button[#class='btn__primary--large from__button--floating']"))).click()
linkedin_urls=['https://www.linkedin.com/in/julie-migliacci-revent/', 'https://www.linkedin.com/in/kathleen-meyers-126a7931']
for linkedin_url in linkedin_urls:
driver.get(linkedin_url)
looking_for_element = True
ldmore = ''
while looking_for_element:
elements = driver.find_elements_by_xpath('/html/body/div[7]/div[3]/div/div/div/div/div[2]/main/div[2]/div[6]/div/section/div[2]/button/span[1]')
if len(elements) > 0:
ldmore = elements[0]
ldmore.click()
looking_for_element = False
else:
global_copyright = driver.find_elements_by_css_selector('#globalfooter-copyright')
if len(global_copyright) > 0:
looking_for_element = False
else:
body = driver.find_element_by_css_selector('body')
sleep(5)
body.send_keys(Keys.PAGE_DOWN)
I've not seen a discussion on SO about element issues when the underlying solution is not visibility. The code is designed to stop once the element is located -- and is performing this correctly. But it just isn't clicking on the element. I'm not sure why this is.
Locations I've tried:
absolute xpath:
driver.find_element_by_xpath('/html/body/div[7]/div[3]/div/div/div/div/div[2]/main/div[2]/div[6]/div/section/div[2]/button/span[1]').click()
relative xpath:
//span[contains(text(),'Show more')]
class name:
pv-profile-section__card-action-bar pv-skills-section__additional-skills artdeco-container-card-action-bar artdeco-button artdeco-button--tertiary artdeco-button--3 artdeco-button--fluid" aria-controls="skill-categories-expanded
css:
body.render-mode-BIGPIPE.nav-v2.theme.theme--classic.ember-application.boot-complete.icons-loaded:nth-child(2) div.application-outlet:nth-child(77) div.authentication-outlet:nth-child(3) div.extended div.body div.pv-profile-wrapper.pv-profile-wrapper--below-nav div.self-focused.ember-view div.pv-content.profile-view-grid.neptune-grid.two-column.ghost-animate-in main.core-rail div.profile-detail div.pv-deferred-area.ember-view:nth-child(6) div.pv-deferred-area__content section.pv-profile-section.pv-skill-categories-section.artdeco-container-card.ember-view div.ember-view > button.pv-profile-section__card-action-bar.pv-skills-section__additional-skills.artdeco-container-card-action-bar.artdeco-button.artdeco-button--tertiary.artdeco-button--3.artdeco-button--fluid
UPDATE:
Tried the JS force, it clicked! But threw up the error: selenium.common.exceptions.WebDriverException: Message: unknown error: Cannot read property 'click' of null
if len(elements) > 0:
ldmore = elements[0]
ldmorebtn = driver.find_element_by_xpath('/html/body/div[7]/div[3]/div/div/div/div/div[2]/main/div[2]/div[6]/div/section/div[2]/button/span[1]').click()
#driver.execute_script("arguments[0].checked = true;", ldmore)
driver.execute_script("arguments[0].click();", ldmore)
The suggestion by #Datanovice to use javascript to force a click worked like a charm. Initially, when I had tried to adapt the solution, I received the error selenium.common.exceptions.WebDriverException: Message: unknown error: Cannot read property 'click' of null.
This error was because I had been using EC.element_to_be_clickable. Instead, when I paired the java method with EC.visibility_of_element_located, the click consistently worked.
The code:
ldmore = WebDriverWait(driver, 30).until(EC.visibility_of_element_located((By.XPATH,'xpath')))
driver.execute_script("arguments[0].click();", ldmore)

Categories