1

I have the following bit of code in python: it opens firefox on a specified page, closes the "accept cookies" window, and scrolls down to click on a button "Carica Altro". When I click the button I get : ElementNotInteractableException: Message: Element <button class="button button--primary medium expanded button--login" type="submit"> could not be scrolled into view but in fact it is visible, because I see it in the UI (as in the picture). result of scrolling with my script

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
from selenium.webdriver.firefox.options import Options as FirefoxOptions
from selenium.webdriver.common.action_chains import ActionChains
import time

my_url='https://www.raiplay.it/programmi/winxclub/episodi/stagione-5'

def main():
  options = FirefoxOptions()
  browser = webdriver.Firefox(options=options)
  browser.implicitly_wait(10)
  browser.get(my_url)
  wait = WebDriverWait(browser, 30)
  try:
    wait.until(EC.element_to_be_clickable((By.CLASS_NAME, "as-oil__btn-primary.as-js-optin"))).click()
    print('Clicked successfully')
  except:
    print('Could not click')
    pass

  l =browser.find_element(By.CLASS_NAME,"button.button--primary.medium.expanded")
  browser.execute_script('window.scrollBy(0, 1500)') 

  time.sleep(10)
  l.click()
  return
1
  • Try searching by just button--primary and click on the last one. If that doesn't work, try clicking on a containing or contained element (like the div or the a). That's how I've solved this sort of problem in the past Commented Apr 10, 2024 at 23:43

2 Answers 2

1

The problem with your code was that your second locator wasn't unique enough to find only the element you wanted. It was in fact finding two elements, the first of which was a different element, a BUTTON tag (seen in the error message you posted), instead of the A tag you wanted. Changing the locator fixes the problem without the scrolling or sleeps.

I have confirmed that the code below works.

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = 'https://www.raiplay.it/programmi/winxclub/episodi/stagione-5'
driver = webdriver.Firefox()
driver.maximize_window()
driver.get(url)

wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[data-qa='oil-YesButton']"))).click()
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a[title='Carica altro']"))).click()

Some feedback...

  1. The Selenium lead and contributors have repeatedly said not to use implicit waits. Use WebDriverWait instead.
  2. If you insist on using implicit waits, definitely don't mix implicit and WebDriverWait. It can cause strange issues.
  3. IMHO 30s is way too long to wait. I would default to something closer to 10s. You don't want it too low or it won't help with small slowdowns but you don't want it too long or it will cause extreme slowdowns in your script if it does timeout.
  4. You are using By.CLASS_NAME incorrectly. It's intended to be passed a single class name but you are passing it a modified CSS selector.
  5. You don't need to scroll here... Selenium will scroll for you.
  6. Using sleeps is a bad practice. Use WebDriverWait instead.
Sign up to request clarification or add additional context in comments.

1 Comment

I am using selenium because I want to generate the full html of the page, after interacting with the two buttons. Now it is working, but I am not sure if there is a smarter way to do this
0

You can use https://github.com/seleniumbase/SeleniumBase to get around your issues and simplify your script. pip install seleniumbase, and then run with python:

from seleniumbase import SB

with SB() as sb:
    sb.open("https://www.raiplay.it/programmi/winxclub/episodi/stagione-5")
    sb.click('button[data-qa="oil-YesButton"]')
    sb.scroll_to_bottom()
    sb.sleep(0.5)
    sb.scroll_to('a[title="Carica altro"]')
    sb.sleep(0.5)
    sb.click('a[title="Carica altro"]')

    breakpoint()

To continue from the breakpoint(), type c and press Enter.

3 Comments

Installing a whole new package isn't necessary to solve this issue. The screen doesn't need to be scrolled and sleeps are a bad practice, you should instead use WebDriverWait.
The sleeps are for show. SeleniumBase has automatic waiting. WebDriverWait is now considered bad practice because it leads to overly long lines of code.
If it's for show, remove them. There's no point in slowing down your script for "show". No, WebDriverWait is not a bad practice because the lines of code are long... that's ridiculous. Using sleep and implicit wait are bad practices according to the Selenium lead and contributors. The Selenium documentation states that WebDriverWaits are a recommended practice so ... who stated WebDriverWaits are a bad practice?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.