Getting a 2FA e-mail sent on Palo Alto site with python and selenium

I am attempting to write a script that will download a file from the Palo Alto Networks website.
The script I am writing is successfully entering username and password, but then the 2FA section comes, and I am having trouble getting selenium to locate/press the “Send me the code” button.

The script I have so far is as follows:

import os
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from dotenv import dotenv_values

# Load the .env file into a variable
config = dotenv_values(".env")

# Read username and password from the environment file
username = config['USERNAME']
password = config['PASSWORD']

# URL of the Palo Alto login page
url = "https://sso.paloaltonetworks.com/"

# Path to your WebDriver (download the appropriate one for your browser)
# For Chrome, download from https://sites.google.com/chromium.org/driver/
# webdriver_path = r"c:\Users\tdadmin\Documents\Python\PaloAlto\RegListDownload\chromedriver-win64\chromedriver.exe"

# Create a new instance of the Chrome driver
driver = webdriver.Chrome()

try:
    # Open the login page
    driver.get(url)

    # Find the username input field and fill them
    username_field = driver.find_element(By.ID, "idp-discovery-username")
    username_field.send_keys(username)

    # Submit the username
    username_field.send_keys(Keys.RETURN)

    # Wait for the password field to load
    WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, "okta-signin-password"))
    )

    # Find the password input field and fill them
    password_field = driver.find_element(By.ID, "okta-signin-password")
    password_field.send_keys(password)

    # Submit the password
    password_field.send_keys(Keys.RETURN)

    # Wait for the 2FA page to load
    WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.CSS_SELECTOR, "button button-primary"))
    )

    # Press the button to send the e-mail
    send_2FA = driver.find_element(By.CSS_SELECTOR, "button button-primary")
    send_2FA.click();

    # Provide an opportunity for the user to enter 2FA code manually
    # input("Please enter your 2FA code, then press Enter to continue...")

    # You may need to locate and interact with the "Submit" button after entering 2FA code

    # For example:
    # submit_button = driver.find_element(By.ID, "submit_button_id")
    # submit_button.click()

    # Now, you can perform actions on the authenticated session
    # (e.g., navigate to the desired page and download a file)

finally:
    # Close the browser window
    driver.quit()

The xpath of the “button” I want to press is:
/html/body/div/div[2]/div/div[2]/div[1]/main/div[2]/div/div/form/div[2]/input

I think your css selecter for the button should be

".button.button-primary"

You current css-selecter (“button button-primary”) tries to find an element <button/> en in that element find a element <button-primary/>.

In css you select a class by using a . in front of the classname. And if you want to find an element with multiple classes they should be sticked together without the use of spaces.

Leave a Comment