Search code examples
pythonhtmlseleniumweb-scrapingfindelement

Selenium find element by class breaking code


My program checks a login page for available combinations. Upon first opening up the page, there is a "check availability" button, which has an ID which Selenium is able to find/use to click.

If the username is taken, a new button pops up which says "check another combination", however the DOM inspector only gives the following information about the second button:

<a class="btn btn-outline-primary btn-block mt-4" href="" role="button" data-ng-click="combination.reset()">
                                    Check another combination
                                </a>

I have tried finding this button by CLASS, CLASSNAME, copying and pasting the XPATH from the inspector and all these have lead to not only the button clicking not working, but the entering and submitting of the intial combination also ceasing to work.

Hoping someone can suggest how to identify this button from the given information. For reference, here is one of the lines I tried:

check_another_combo_button = driver.find_element(By.CLASS, "btn btn-outline-primary btn-block mt-4")

Here is my full code:

from selenium import webdriver
from selenium.webdriver.common.by import By
from webdriver_manager.firefox import GeckoDriverManager
import time

driver = webdriver.Firefox(executable_path=GeckoDriverManager().install())
driver.maximize_window()
site = "https://www......"
driver.get(site)

combination_input_field = driver.find_element(By.ID, "userCombination")
check_availability_button = driver.find_element(By.ID, "btn_fQPAC_submit")

combination_input_field.send_keys(77777) #77777 is one of the unavailable combos
check_availability_button.click()
time.sleep(2)
check_another_combo_button = driver.find_element(By.CLASS_NAME, "btn btn-outline-primary btn-block mt-4")
check_another_combo_button.click()

Solution

  • I suspect you want to check for inputs say inputs in a loop. Here is the solution using both chrome and firefox.

    Solution using chrome driver :

    from selenium import webdriver
    from selenium.webdriver.chrome.service import Service
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.support.ui import WebDriverWait
    
    chrome_path = r"C:\Users\hpoddar\Desktop\Tools\chromedriver_win32\chromedriver.exe"
    
    s = Service(chrome_path)
    url = 'https://www......'
    driver = webdriver.Chrome(service=s)
    driver.get(url)
    
    inputs = ['77777', '88888', '99999', '11111']
    for plate in inputs:
        combination_input_field = driver.find_element(By.ID, "qPlateCombination")
        check_availability_button = driver.find_element(By.ID, "btn_fQPAC_submit")
        combination_input_field.send_keys(plate)
        check_availability_button.click()
    
        element = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".btn.btn-outline-primary.btn-block.mt-4")))
        check_another_combo_button = driver.find_element(By.CSS_SELECTOR, ".btn.btn-outline-primary.btn-block.mt-4")
        check_another_combo_button.click()
    

    Solution using Geckodriver :

    To use Geckodriver, all you need to add is

    from webdriver_manager.firefox import GeckoDriverManager
    from selenium.webdriver.chrome.service import Service
    

    and change driver initialization line to

    s = Service(executable_path=GeckoDriverManager().install())
    webdriver.Firefox(service=s)
    driver.maximize_window()