I am practicing with selenium to log into a website and grab the mortage ticket (print/save/download it as pdf).
The logging page is as follows:
Field 1: Contract number
Field 2: National user-id
Botton: Botton to validate the contract
Field 3: Requests some aleatory personal info (day of birh, mother's name, zip code, National Health ID, voter registration etc.) each time the page is accessed/refreshed
When I log to it (every month) throughout the user page, when it comes to some aleatory info that I don't know by heart (such as National Heatlh ID or voter registration), I refresh the page until it brings me some easy to remember info(phone number, zip code, etc.).
What can I do to go through this last field that requests personal information in a random way(some that I know by heart, others I do not)?
The website code referring to the 3rd field is as follows. The parameters name="zipCode" and placeholder="Zip Code" parts are the ones that keeps changing their values each time the page is refreshed.
input id="aleatoryField"
_ngcontent-iqu-c4="" autocomplete="off"
formcontrolname="aleatoryField" inputmode="decimal" matinput=""
pattern="[0-9]*" required="" name="zipCode" placeholder="Zip Code"
aria-describedby="mat-error-2" aria-invalid="true" aria-required="true"
input id="aleatoryField"
_ngcontent-iqu-c4="" autocomplete="off"
formcontrolname="aleatoryField" inputmode="decimal" matinput=""
pattern="[0-9]*" required="" name="voterId" placeholder="Voter Registration"
aria-describedby="mat-error-2" aria-invalid="true" aria-required="true"
input id="aleatoryField"
_ngcontent-iqu-c4="" autocomplete="off"
formcontrolname="aleatoryField" inputmode="decimal" matinput=""
pattern="[0-9]*" required="" name="yearBirth" placeholder="Year of Birth"
aria-describedby="mat-error-2" aria-invalid="true" aria-required="true"
# MY CURRENT CODE
from selenium import webdriver
driver = webdriver.Firefox(executable_path="./geckodriver.exe" )
# open the website
driver.get("https://www.habitacaodigital.caixa.gov.br/acesso-cliente")
# FIELD 1: contract info
contract = driver.find_element_by_id("contract")
national_id = driver.find_element_by_id("nationalId")
# FIELD 2: filling the contract info
contract.send_keys("123")
national_id.send_keys("321")
# botton
validate_contract = driver.find_element_by_id("validate_contract")
validate_contract.click()
# FIELD 3: aleatory personal info field (cellphone number, zip code, day of birth, mother's name...)
# aleatory_field = driver.find_element_by_id("aleatoryField")
# aleatory_field.send_keys("HOW TO DEAL WITH THIS PART OVER HERE?")
# undetected Selenium suggestion
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input#aleatoryField[formcontrolname='aleatoryField']"))).send_keys("234567")
# LOGGING BOTTON
btn_logging = driver.find_element_by_id("btn_access")
btn_logging.click()
Result with undetected Selenium first suggestion added in
CodePudding user response:
To send a character sequence to the <input>
element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input#aleatoryField[formcontrolname='aleatoryField']"))).send_keys("234567")
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@id='aleatoryField' and @formcontrolname='aleatoryField']"))).send_keys("234567")
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
CodePudding user response:
It seems you have no problem with dynamic element since element id
was never changed. you have problem with input values based on type of the field name
appeared on the screen on each login.
You can use python switch case and configured all return type attribute name
and then call the function and if it matches the specific name
then execute that block only with your input.
def SetInputValue(element, elementAttVal):
match elementAttVal:
case "zipCode":
element.send_keys("400910")
case "voterId":
element.send_keys("1234588999")
case "yearBirth":
element.send_keys("1990")
//identify the element
element=WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "input#aleatoryField")))
//Get the name attribute value
elementAttVal=element.get_attribute("name")
print(elementAttVal)
//Set the input based on name attribute
SetInputValue(element,elementAttVal)