Check if element exists selenium python

Viewed 7916

I am training on selenium python and I could do login fields and need to check for specific element after login process succeed. The element is defined by class name like that

if len(driver.find_element(By.CLASS_NAME, 'userIDSection').text)==30:
    print('Successful Login')
    break

If the login is successful I didn't get errors, but when failed I got "no such element: Unable to locate element". How can I check for the element correctly to skip such errors?

** Trying this code

WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[name='login']"))).click()
time.sleep(3)
if len(driver.find_elements(By.CLASS_NAME, 'userIDSection'))>0:
    print('Successful Login')
    break
print('Login Failure')

I have been able to login but got an error at this line

TimeoutException                          Traceback (most recent call last)
<ipython-input-44-1f801f6ca398> in <module>
     28     WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "txtCaptcha"))).send_keys(captcha)
     29 
---> 30     WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[name='login']"))).click()
     31     time.sleep(3)
     32     if len(driver.find_elements(By.CLASS_NAME, 'userIDSection'))>0:

C:\ProgramData\Anaconda3\lib\site-packages\selenium\webdriver\support\wait.py in until(self, method, message)
     78             if time.time() > end_time:
     79                 break
---> 80         raise TimeoutException(message, screen, stacktrace)
     81 
     82     def until_not(self, method, message=''):

TimeoutException: Message: 

The code at the point of checking the element is supposed to print "Login Successful" and break the loop that starts with while True:

** This is the full code, it works and the login is OK but I got errors after the break point I think

from selenium import webdriver 
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.common.exceptions import NoSuchElementException
import pytesseract
from PIL import Image
import time

def getCaptcha(img):
    pytesseract.pytesseract.tesseract_cmd=r'C:\\Program Files\\Tesseract-OCR\\tesseract.exe'
    img=Image.open(img)
    text=pytesseract.image_to_string(img, lang='eng',config='--psm 10 --oem 3 -c tessedit_char_whitelist=0123456789')
    return text

driver = webdriver.Chrome("C:/chromedriver")
driver.get("https://eservices.moj.gov.kw/")
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CLASS_NAME, "headerTabLeft"))).click()

while True:
    WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "txtUserID"))).send_keys("username")
    WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "txtPWD"))).send_keys("password")
    
    imgName = 'Output.png'
    imgElement = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//*[@id='frmLogin']/table[1]/tbody/tr[1]/td/img")))
    imgElement.screenshot(imgName)
    time.sleep(5)
    captcha = getCaptcha(imgName)
    WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "txtCaptcha"))).send_keys(captcha)
    
    WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[name='login']"))).click()
    time.sleep(3)
    
    try:
        element = driver.find_element(By.CLASS_NAME, 'userIDSection')
        break
    except:
    #except NoSuchElementException:
        print("No Element Found")
    
print('Successful Login')
4 Answers

Use the .find_elements (note the plural) method:

if len(driver.find_elements(By.CLASS_NAME, 'userIDSection'))>0:
    # DO YOUR THING

So if there are no elements with that class name, you will get len = 0, but no error.

Use try/except to catch the exception.

from selenium.common.exceptions import NoSuchElementException

try:
    elem = driver.find_element(By.CLASS_NAME, 'userIDSection')
    if len(elem.text) == 30:
        print("Login OK.")
    else:
        print("Elem found but length is not correct, handle this case.")
except NoSuchElementException:
    print("Failed logging in?")

BTW, you should use fluent wait: waits

Your approach is correct here, and the behavior is expected. What you can do is wrap the find in a try - except block and process the exception as you like:

try:
    el = driver.find_element(By.CLASS_NAME, 'userIDSection')
    if len(el.text) == 30:
        print('Successful Login')
        break
    else:
        print("Element found but not valid")
except NoSuchElementException as e:
    print("Log in was unsuccesful: " + repr(e))

After so much time and thanks to you I could solve it like that

from selenium import webdriver 
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.common.exceptions import NoSuchElementException
import pytesseract
from PIL import Image
import time

def getCaptcha(img):
    pytesseract.pytesseract.tesseract_cmd=r'C:\\Program Files\\Tesseract-OCR\\tesseract.exe'
    img=Image.open(img)
    text=pytesseract.image_to_string(img, lang='eng',config='--psm 10 --oem 3 -c tessedit_char_whitelist=0123456789')
    return text

def isElementPresent(locator):
    try:
        driver.find_element(By.CLASS_NAME, locator)
    except NoSuchElementException:
        print ('No Such Element')
        return False
    return True

driver = webdriver.Chrome("C:/chromedriver")
driver.get("https://eservices.moj.gov.kw/")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CLASS_NAME, "headerTabLeft"))).click()

while True:
    try:
        if isElementPresent('userIDSection'):
            print(driver.find_element(By.CLASS_NAME, 'userIDSection').text)
            break
        username = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.ID, "txtUserID")))
        username.clear()
        username.send_keys("username")
        password = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.ID, "txtPWD")))
        password.clear()
        password.send_keys("password")

        imgName = 'Output.png'
        imgElement = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//*[@id='frmLogin']/table[1]/tbody/tr[1]/td/img")))
        imgElement.screenshot(imgName)
        time.sleep(5)
        captcha = getCaptcha(imgName)
        WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.ID, "txtCaptcha"))).send_keys(captcha)

        WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[name='login']"))).click()
        time.sleep(5)
    except:
        print('Timeout')

print('Successful Login')
Related