1

I'm trying to code a bot that will automate a login on a certain page using selenium. I keep getting the same error, and I don't know how to fix it. Please help :=)

Here's the code:

# Importing everything #
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time

# PATH + Driver Setup #
PATH = "C:\Program Files (x86)\chromedriver.exe"
driver = webdriver.Chrome(PATH)

# Getting All Requirements #
driver.get("https://ytmonster.net/login")
time.sleep(5)
imputUsername = driver.find_element(By.ID, "inputUsername")
imputPassword = driver.find_element(By.ID, "inputPassword")
linkClick = driver.find_element(By.CLASS_NAME, "btn btn-success")

# Executing script #
imputUsername.send_keys("mymail@gmail.com")
imputPassword.send_keys("mypassword")
linkClick.click

And here is the error that I get:

C:\Users\Xera\Desktop\YtMonster Bot.py:9: DeprecationWarning: executable_path has been deprecated, please pass in a Service object
  driver = webdriver.Chrome(PATH)

DevTools listening on ws://127.0.0.1:51847/devtools/browser/a848e7ed-d31d-4415-96c5-1a28a4729a17
[8664:1220:0815/155348.366:ERROR:device_event_log_impl.cc(214)] [15:53:48.364] Bluetooth: bluetooth_adapter_winrt.cc:1074 Getting Default Adapter failed.
Traceback (most recent call last):
  File "C:\Users\Xera\Desktop\YtMonster Bot.py", line 16, in <module>
    linkClick = driver.find_element(By.CLASS_NAME, "btn btn-success")
  File "C:\Users\Xera\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 856, in find_element
    return self.execute(Command.FIND_ELEMENT, {
  File "C:\Users\Xera\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 434, in execute
    self.error_handler.check_response(response)
  File "C:\Users\Xera\AppData\Local\Programs\Python\Python310\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 243, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":".btn btn-success"}
  (Session info: chrome=104.0.5112.81)
Stacktrace:
Backtrace:
        Ordinal0 [0x00CA78B3+2193587]
        Ordinal0 [0x00C40681+1771137]
        Ordinal0 [0x00B541A8+803240]
        Ordinal0 [0x00B824A0+992416]
        Ordinal0 [0x00B8273B+993083]
        Ordinal0 [0x00BAF7C2+1177538]
        Ordinal0 [0x00B9D7F4+1103860]
        Ordinal0 [0x00BADAE2+1170146]
        Ordinal0 [0x00B9D5C6+1103302]
        Ordinal0 [0x00B777E0+948192]
        Ordinal0 [0x00B786E6+952038]
        GetHandleVerifier [0x00F50CB2+2738370]
        GetHandleVerifier [0x00F421B8+2678216]
        GetHandleVerifier [0x00D317AA+512954]
        GetHandleVerifier [0x00D30856+509030]
        Ordinal0 [0x00C4743B+1799227]
        Ordinal0 [0x00C4BB68+1817448]
        Ordinal0 [0x00C4BC55+1817685]
        Ordinal0 [0x00C55230+1856048]
        BaseThreadInitThunk [0x766A6739+25]
        RtlGetFullPathName_UEx [0x779F90AF+1215]
        RtlGetFullPathName_UEx [0x779F907D+1165]

How can I fix this? I tried everything but didn't find any answers... Thanks again for the help! :)

Xera
  • 13
  • 4

3 Answers3

0

This is because your page elements get changed after you manipulate it using Selenium. Try other ways to access the desired element such as xpath. Selecting by class often causes this exception as the class of your html elements can change. For example, once a tab is clicked, the class can change to something like: tab-button active, while prior to the clicking, it was something like: tab-button. I recommend using xpath. It is very powerful as it enhances your ability to access items in a relative way from each other. You can for example say I want the i-th children of my first row inside a table inside body inside html tag.

Fatemeh Sangin
  • 558
  • 1
  • 4
  • 19
0

This is one way of accomplishing your task:

from selenium import webdriver
from selenium.webdriver.firefox.service import Service
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.firefox.options import Options as Firefox_Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support import expected_conditions as EC
import time as t

firefox_options = Firefox_Options()

# firefox_options.add_argument("--width=1500")
# firefox_options.add_argument("--height=500")
# firefox_options.headless = True

driverService = Service('chromedriver/geckodriver')

browser = webdriver.Firefox(service=driverService, options=firefox_options)

url = 'https://ytmonster.net/login'

browser.get(url)

WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@id='inputUsername']"))).send_keys('my_great_username')
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@id='inputPassword']"))).send_keys('my really bad password')
print('wrote in my user and pass')
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[text()='Login']"))).click()
print('clicked the login button!')

The setup is Firefox /geckodriver on Linux, however you can adapt it to your own system, just observe the imports, and the part after defining the browser/driver. Selenium docs: https://www.selenium.dev/documentation/

Barry the Platipus
  • 9,594
  • 2
  • 6
  • 30
0

You can't pass multiple classnames as argument using By.CLASS_NAME as:

find_element(By.CLASS_NAME, "classname1 classname2")

Solution

To automate the login process on the webpage you can use locator strategies:

  • Using CSS_SELECTOR:

    driver.execute("get", {'url': 'https://ytmonster.net/login'})
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input#inputUsername"))).send_keys("Xera@stackoverflow.com")
    driver.find_element(By.CSS_SELECTOR, "input#inputPassword").send_keys("XeraXera")
    driver.find_element(By.CSS_SELECTOR, "button.btn.btn-success").click()
    
  • Using XPATH:

    driver.execute("get", {'url': 'https://ytmonster.net/login'})
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@id='inputUsername']"))).send_keys("Xera@stackoverflow.com")
    driver.find_element(By.XPATH, "//input[@id='inputPassword']").send_keys("XeraXera")
    driver.find_element(By.XPATH, "//button[@class='btn btn-success']").click()
    
  • Note : You have to add the following imports :

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
  • Browser Snapshot:

ytmonster

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352