Skip to Content
Course content

430: Building a Simple Job Application Auto-Filler

Click on the "Edit" button in the top corner of the screen to edit your slide content.

When people first try to automate a web form—like a job application—they usually start with a very specific assumption: "I'll just find the element's ID in the HTML and tell Python to put my name in that box."

It sounds logical. You right-click the "First Name" field, see id="fname_123", and write driver.find_element(By.ID, "fname_123").send_keys("Alex"). But then you run it on a different application, or even refresh the page, and the script crashes with a NoSuchElementException. Why? Because modern web frameworks (React, Angular, Vue) often generate dynamic IDs. That "123" at the end might change every single time the page loads. If you rely on those IDs, your bot is brittle and will break almost immediately.

Targeting by Intent instead of ID

Instead of chasing a random string of numbers, you need to look for patterns that are less likely to change. I usually look for name attributes, placeholder text, or relative XPaths. For example, instead of looking for a specific ID, look for an input field that is adjacent to a label containing the word "Email".

Here is the difference in approach. Instead of a fragile ID, we use a CSS selector that looks for an input with a name attribute containing "email":

# The fragile way
# driver.find_element(By.ID, "user_email_8821").send_keys("me@example.com")

# The resilient way
driver.find_element(By. Cortana.CSS_SELECTOR, "input[name*='email']").send_keys("me@example.com")

The *= operator in the CSS selector means "contains." As long as the developer keeps the word "email" in the name attribute, your script keeps working. It's a much safer bet.

The Illusion of the Loaded Page

Another thing I see beginners struggle with is timing. You'll write a script that works perfectly when you run it slowly, but fails when the network lags. You might be tempted to throw time.sleep(5) everywhere. Please, don't do that. It's a waste of time and makes your script feel sluggish.

The professional way to handle this is with Explicit Waits. You tell Python to wait up to ten seconds, but to proceed the microsecond the element actually appears. This makes your auto-filler snappy and reliable.

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# Wait until the 'Apply' button is actually clickable before trying to click it
wait = WebDriverWait(driver, 10)
apply_button = wait.until(EC.element_to_be_clickable((By.ID, "submit-application")))
apply_button.click()

Separating Your Bio from Your Logic

If you hard-code your name and experience directly into the automation logic, you're creating a maintenance nightmare. What happens when you want to use a different version of your resume for a different role? I always suggest moving your personal data into a dictionary or a JSON file.

By treating your personal info as "data" and your Selenium code as the "engine," you can swap out your profile without touching a single line of executable code. Here is how a simple, scalable auto-filler looks when put together:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# Your "Profile" - keep this separate!
my_profile = {
    "first_name": "Jordan",
    "last_name": "Smith",
    "email": "jordan.smith@email.com",
    "phone": "555-0123",
    "linkedin": "linkedin.com/in/jordansmith"
}

driver = webdriver.Chrome()
driver.get("https://example-job-board.com/apply")

wait = WebDriverWait(driver, 10)

# We map the profile keys to the CSS selectors we found on the page
field_map = {
    "first_name": "input[name*='first']",
    "last_name": "input[name*='last']",
    "email": "input[name*='email']",
    "phone": "input[name*='phone']",
    "linkedin": "input[name*='linkedin']"
}

for key, selector in field_map.items():
    element = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, selector)))
    element.send_keys(my_profile[key])

print("Form filled successfully!")



📋 Practical Task

The Multi-Profile Application Automator

Build a Python script that can handle multiple "personas." Instead of a single dictionary, create a list of dictionaries (e.g., profiles = [{"name": "Dev Profile", ...}, {"name": "Manager Profile", ...}]).

Your script should:

  • Prompt the user in the console to choose which profile to use.
  • Use an Explicit Wait to ensure the page is loaded.
  • Target at least three fields (Name, Email, and a "Portfolio URL") using CSS selectors that look for "contains" (*=) rather than exact IDs.
  • Navigate to a local HTML file you've created (or a test site like practicetestautomation.com) to demonstrate the filling process.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.