How to wait until element is visible in Selenium?

Learn how to effectively use Selenium to ensure an element is visible before interacting with it. This guide provides a straightforward approach to handling visibility issues, enhancing your scraping efficiency and accuracy.

Best practices

  • Use explicit waits with `WebDriverWait` and `expected_conditions` to handle elements that may take time to become visible, ensuring a more reliable element interaction.

  • Prefer `visibility_of_element_located` over `presence_of_element_located` in explicit waits when you need to interact with the element, as it confirms both presence and visibility.

  • Avoid mixing implicit and explicit waits as it can lead to unpredictable wait times and increase the overall test execution time.

  • Set a reasonable timeout for `WebDriverWait` to balance between adequate wait time and test execution efficiency, considering network speed and page complexity.

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

# Initialize WebDriver
driver = webdriver.Chrome()

# Navigate to the target URL
driver.get("https://sandbox.oxylabs.io/products")

# Explicit wait: wait until an element is visible
element = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.ID, "target-element-id"))
)

# Perform actions with the element
element.click()

# Implicit wait: set a wait time for all elements
driver.implicitly_wait(10) # Waits up to 10 seconds before throwing an error

# Find an element that should be visible within 10 seconds
another_element = driver.find_element(By.CLASS_NAME, "another-target-class")
another_element.click()

# Clean up: close the browser
driver.quit()

Common issues

  • Ensure that the correct locator strategy and identifier are used in `By.ID` or `By.CLASS_NAME` to avoid `NoSuchElementException`.

  • Regularly update your Selenium WebDriver and browser to the latest versions to avoid compatibility issues with new web technologies.

  • Check for any parent elements with visibility restrictions like `display: none` that might be hiding the desired element.

  • Use `try-except` blocks to handle exceptions gracefully when an element is not found or not visible within the expected time frame.

# Incorrect locator strategy or identifier
element = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.ID, "incorrect-id"))
)

# Correct locator strategy and identifier
element = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.ID, "correct-id"))
)

# Outdated WebDriver or browser version
driver = webdriver.Chrome() # May fail if Chrome or WebDriver is not up-to-date

# Updated WebDriver and browser
driver = webdriver.Chrome('/path/to/updated/chromedriver') # Assuming updated driver is used

# Element hidden by parent with display: none
element = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.ID, "hidden-by-parent"))
)

# Checking parent visibility before accessing element
parent = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.ID, "parent-id"))
)
if parent.value_of_css_property("display") != "none":
element = driver.find_element(By.ID, "child-id")

# No exception handling
element = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.ID, "might-not-exist"))
)

# Using try-except for exception handling
try:
element = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.ID, "might-not-exist"))
)
except TimeoutException:
print("Element not found within the time frame.")

Try Oyxlabs' Proxies & Scraper API

Residential Proxies

Self-Service

Human-like scraping without IP blocking

From

8

Datacenter Proxies

Self-Service

Fast and reliable proxies for cost-efficient scraping

From

1.2

Web scraper API

Self-Service

Public data delivery from a majority of websites

From

49

Useful resources

Get the latest news from data gathering world

I'm interested