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
fromseleniumimportwebdriver

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.

fromseleniumimportwebdriver
fromselenium.webdriver.common.byimportBy

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.

fromseleniumimportwebdriver
fromselenium.webdriver.common.byimportBy
fromselenium.webdriver.support.uiimportWebDriverWait
fromselenium.webdriver.supportimportexpected_conditionsasEC

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

fromseleniumimportwebdriver
fromselenium.webdriver.common.byimportBy
fromselenium.webdriver.support.uiimportWebDriverWait
fromselenium.webdriver.supportimportexpected_conditionsasEC

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.textforrinresults[:5]]
print(titles)

driver.quit()

Example 2: Run Chrome in headless mode

Headless mode helps on servers and CI.

fromseleniumimportwebdriver
fromselenium.webdriver.chrome.optionsimportOptions

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

fromseleniumimportwebdriver

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

driver.save_screenshot("page.png")

driver.quit()

Example 4: Get attributes and links

fromseleniumimportwebdriver
fromselenium.webdriver.common.byimportBy

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

fromseleniumimportwebdriver

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

fromseleniumimportwebdriver
fromselenium.webdriver.common.byimportBy
fromselenium.webdriver.support.uiimportWebDriverWait
fromselenium.webdriver.supportimportexpected_conditionsasEC

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()
exceptException:
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

importtime
fromseleniumimportwebdriver

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.

fromseleniumimportwebdriver
fromselenium.webdriver.common.byimportBy
fromselenium.webdriver.support.uiimportWebDriverWait
fromselenium.webdriver.supportimportexpected_conditionsasEC

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.

fromselenium.webdriver.common.byimportBy

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.

fromseleniumimportwebdriver

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.