Selenium IndexError on find_elements[0]: Fix (2026)

You called driver.find_elements(By.CSS_SELECTOR, ".price")[0].text and Python crashed with IndexError because the page hadn’t finished loading or the selector matched zero elements. Selenium’s find_elements (plural) returns an empty list when nothing matches, vs find_element (singular) which raises NoSuchElementException.

Selenium IndexError on find_elements[0] Fix (2026)
Selenium IndexError on find_elements[0] Fix (2026)

📌 Quick answer: Use WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".price"))) to wait until the element appears (up to 10 sec). For “first match” use find_element (singular). Never index into find_elements without checking the list is non-empty.

Cause 1: Element not loaded yet

JavaScript-rendered pages need time. find_elements runs immediately and gets nothing.

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

# ❌ Element not yet on page
price = driver.find_elements(By.CSS_SELECTOR, ".price")[0].text

# ✓ Wait up to 10 sec
WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.CSS_SELECTOR, ".price"))
)
price = driver.find_element(By.CSS_SELECTOR, ".price").text

Cause 2: Wrong selector or A/B test variant

Selector matches in your test environment but not in production due to CSS class change or A/B test.

# Use multiple fallback selectors
selectors = [".price", ".product-price", "[data-test='price']"]
for sel in selectors:
    els = driver.find_elements(By.CSS_SELECTOR, sel)
    if els:
        price = els[0].text
        break
else:
    price = None

Cause 3: find_element vs find_elements confusion

find_element raises NoSuchElementException on no match. find_elements returns empty list.

from selenium.common.exceptions import NoSuchElementException

try:
    price = driver.find_element(By.CSS_SELECTOR, ".price").text
except NoSuchElementException:
    price = None
# Or just use find_elements and check
els = driver.find_elements(By.CSS_SELECTOR, ".price")
price = els[0].text if els else None

Prevention

  1. Default to WebDriverWait + presence_of_element_located for any JS-rendered content
  2. Use find_element (singular) when you expect exactly one match
  3. Use find_elements (plural) + iterate when zero or more matches are acceptable
  4. Catch NoSuchElementException on find_element instead of bare except

Frequently Asked Questions

What’s the difference between find_element and find_elements in Selenium?

find_element (singular) returns the first match or raises NoSuchElementException. find_elements (plural) returns a list of all matches (possibly empty). For one element use find_element; for multiple use find_elements with iteration.

How do I wait for an element to appear before accessing it?

Use WebDriverWait: WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, ‘.price’))). It polls every 500ms for up to 10 seconds and raises TimeoutException if the element doesn’t appear.

What’s the difference between presence_of_element_located and visibility_of_element_located?

presence_of: the element exists in the DOM (may be hidden). visibility_of: the element exists AND has non-zero size AND display is not ‘none’. Use visibility when you intend to click/read; presence when DOM existence is enough.

How do I handle Selenium A/B test variants with different selectors?

Try each selector in a loop with a list of fallbacks. for sel in [primary, fallback1, fallback2]: els = driver.find_elements(…); if els: break. Don’t rely on a single selector in production scrapers.

Why does my Selenium test work locally but fail in CI?

Usually timing: CI environments are slower, so explicit waits become critical. Replace any time.sleep() with WebDriverWait. Also check headless mode differences and screen resolution affecting visibility checks.

Leave a Comment