Search code examples
pythonselenium-webdriverxpathcss-selectorswebdriverwait

How to find an element with multiple class names using Xpath or CssSelector


I want to access this element:

div data-v-658f4ceb="" class="trn-gamereport-list trn-gamereport-list--compact">

I know that since it has multiple names in the class I would need to use either the XPath or CSS selector method to access it but whenever I try either of these codes:

from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver import Chrome
import pandas as pd
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from time import sleep

driver = webdriver.Chrome()
url = "https://destinytracker.com/destiny-2/profile/psn/4611686018440125811/matches?mode=crucible"
driver.get(url)
crucible_content = driver.find_element(By.XPATH, "//div[contains(@class, 'trn-gamereport-list') and contains(@class, 'trn-gamereport-list--compact')]")
crucible_content = driver.find_element(By.CSS_SELECTOR, "div.trn-gamereport-list.trn-gamereport-list--compact")

I get this error:

"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/selenium/webdriver/remote/errorhandler.py", line 245, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//div[contains(@class, 'trn-gamereport-list') and contains(@class, 'trn-gamereport-list--compact')]"}

I was wondering if anyone could help me in figuring out what exactly I'm doing wrong.


Solution

  • The elements are dynamic elements, so to locate the elements within the website you need to induce WebDriverWait for the visibility_of_element_located() and you can use either of the following locator strategies:

    • Using CSS_SELECTOR:

      driver.get("https://destinytracker.com/destiny-2/profile/psn/4611686018440125811/matches?mode=crucible")
      crucible_content = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.trn-gamereport-list.trn-gamereport-list--compact")))
      
    • Using XPATH:

      driver.get("https://destinytracker.com/destiny-2/profile/psn/4611686018440125811/matches?mode=crucible")  
      crucible_content = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//div[@class='trn-gamereport-list trn-gamereport-list--compact']")))
      
    • Note : You have to add the following imports :

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