How to Use Selenium in Python

What you’ll build or solve

You’ll automate a browser with Python to open pages, find elements, click, type, and read results.

When this approach works best

Selenium works best when you:

  • Test a web app end to end, like logging in and checking that a button triggers the right page.
  • Automate a website that needs JavaScript to render content, where requests + HTML parsing misses the data.
  • Fill out forms and click through steps, like booking flows or internal admin tools.

Avoid Selenium for simple pages that do not need a real browser. In those cases, requests and an HTML parser run faster and break less often.

Prerequisites

  • Python installed
  • You can run a Python script from your terminal

Step-by-step instructions

1) Install Selenium and start a browser

Install Selenium, then create a webdriver instance. Selenium Manager can download a compatible browser driver automatically in many setups.

python -m pip install selenium
from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://example.com")

print(driver.title)

driver.quit()

What to look for:

If Chrome opens and closes immediately, your script finished successfully. If you see a driver error, update Selenium first and check that your browser is installed.


2) Find elements on the page

Prefer stable locators such as IDs, names, or dedicated test attributes. CSS selectors are usually the most flexible.

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://example.com")

heading = driver.find_element(By.CSS_SELECTOR, "h1")
print(heading.text)

driver.quit()

Option A: Locate by ID (often the simplest when available)

button = driver.find_element(By.ID, "submit")

Option B: Locate multiple elements

links = driver.find_elements(By.CSS_SELECTOR, "a")
print("links:", len(links))

What to look for:

find_element(...) raises an exception if nothing matches. find_elements(...) returns an empty list.


3) Interact with elements and wait for them to be ready

Most flaky Selenium scripts fail because the page has not finished rendering. Use explicit waits so you click and read elements only when they are ready.

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

driver = webdriver.Chrome()
driver.get("https://example.com/login")

wait = WebDriverWait(driver, 10)

email = wait.until(EC.visibility_of_element_located((By.NAME, "email")))
password = driver.find_element(By.NAME, "password")

email.clear()
email.send_keys("mina@example.com")
password.send_keys("secret")

submit = driver.find_element(By.CSS_SELECTOR, "button[type='submit']")
submit.click()

welcome = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".welcome")))
print(welcome.text)

driver.quit()

What to look for:

If you get ElementNotInteractableException or ElementClickInterceptedException, the element exists but is not ready. A wait for visibility or clickability usually fixes it.


Examples you can copy

Example 1: Search on a page and read results

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

driver = webdriver.Chrome()
driver.get("https://example.com")

wait = WebDriverWait(driver, 10)

search = wait.until(
    EC.visibility_of_element_located((By.CSS_SELECTOR, "input[type='search']"))
)
search.send_keys("python")

driver.find_element(By.CSS_SELECTOR, "button.search").click()

results = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".result")))
titles = [r.text for r in results[:5]]
print(titles)

driver.quit()

Example 2: Run Chrome in headless mode

Headless mode helps on servers and CI.

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.add_argument("--headless=new")

driver = webdriver.Chrome(options=options)
driver.get("https://example.com")

print(driver.title)

driver.quit()

Example 3: Take a screenshot for debugging

from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://example.com")

driver.save_screenshot("page.png")

driver.quit()

Example 4: Get attributes and links

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://example.com")

first_link = driver.find_element(By.CSS_SELECTOR, "a")
print(first_link.get_attribute("href"))

driver.quit()

Example 5: Switch to a new tab

from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://example.com")

driver.execute_script("window.open('https://example.com/docs', '_blank');")

tabs = driver.window_handles
driver.switch_to.window(tabs[-1])

print(driver.title)

driver.quit()

Example 6: Close popups or cookie banners

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

driver = webdriver.Chrome()
driver.get("https://example.com")

wait = WebDriverWait(driver, 5)

try:
    accept = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.cookie-accept")))
    accept.click()
except Exception:
    pass

print(driver.title)
driver.quit()

Common mistakes and how to fix them

Mistake 1: Using time.sleep() everywhere instead of explicit waits

What you might do

import time
from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://example.com")

time.sleep(3)
driver.find_element("css selector", ".buy").click()

Why it breaks

A fixed sleep can be too short on slow loads, or waste time on fast loads.

Fix

Use an explicit wait for the element you need.

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

driver = webdriver.Chrome()
driver.get("https://example.com")

wait = WebDriverWait(driver, 10)
buy = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".buy")))
buy.click()

driver.quit()

Mistake 2: Writing a locator that matches the wrong element

What you might do

driver.find_element("css selector", "button").click()

Why it breaks

Many pages have multiple buttons, so the first match may change and your click hits the wrong UI.

Fix

Use a more specific selector, ideally tied to an ID, name, or test attribute.

from selenium.webdriver.common.by import By

driver.find_element(By.CSS_SELECTOR, "button[type='submit']").click()

Mistake 3: Forgetting to close the browser

What you might do

driver = webdriver.Chrome()
driver.get("https://example.com")
# script ends without quitting

Why it breaks

Chrome processes can pile up and slow down your machine.

Fix

Call quit() in a finally block so cleanup runs even if something fails.

from selenium import webdriver

driver = webdriver.Chrome()
try:
    driver.get("https://example.com")
    print(driver.title)
finally:
    driver.quit()

Troubleshooting

If you see ModuleNotFoundError: No module named 'selenium', install it with python -m pip install selenium and make sure you use the same Python you run the script with.

If you see a driver or browser mismatch error, upgrade Selenium and update your browser. Selenium Manager works best on recent versions.

If you see NoSuchElementException, your selector did not match. Double check the CSS selector, and add an explicit wait if the element appears after rendering.

If you see StaleElementReferenceException, the page re-rendered and the element handle becomes invalid. Find the element again after the update, or wait for a stable state.

If clicking fails with “intercepted” errors, a banner or overlay is in front. Close the popup first, or wait for the overlay to disappear.

If headless mode behaves differently, try setting a window size:

options.add_argument("--window-size=1280,800")

If a script seems to hang, lower the wait timeout and print progress messages between steps so you know where it stops.


Quick recap

  • Install Selenium and start a webdriver for Chrome.
  • Locate elements with By.CSS_SELECTOR, By.ID, or By.NAME.
  • Use explicit waits (WebDriverWait) before reading, clicking, or typing.
  • Use send_keys() for typing and .click() for actions.
  • Always call driver.quit() to close the browser.