You can select elements by class in XPath using contains(@class, "class-name") or @class="class-name".
contains(@class, "class-name") matches any element whose class attribute contains the text class-name. That means it also matches partial class names. The second expression only matches elements whose class attribute is exactly class-name, so it won't match elements with additional classes.
If you want to match a single class without matching partial class names, use contains(concat(" ", normalize-space(@class), " "), " class-name "). It matches class="class-name active", but it won't match class="class-name-large".
Here is a sample XPath code in Selenium that demonstrates all three approaches:
from urllib.parse import quote
from selenium import webdriver
from selenium.webdriver.common.by import By
# A local HTML snippet, so no external page is required.
# This example assumes Selenium can launch Chrome in your environment.
html = """
<html>
<body>
<h1 class="mb-[33px]">The Best Web Scraping API</h1>
<h1 class="mb-[33px] hero-title">Web Scraping API with multiple classes</h1>
<h1 class="mb-[33px]-large">Web Scraping API with a similar class name</h1>
</body>
</html>
"""
# Launch a new Chrome browser instance
driver = webdriver.Chrome()
try:
# Load the HTML directly via a data URL
driver.get("data:text/html;charset=utf-8," + quote(html))
# Example 1
# contains(@class, ...) matches any element whose class attribute
# contains "mb-[33px]", including partial class names.
contains_matches = driver.find_elements(
By.XPATH,
"//h1[contains(@class, 'mb-[33px]')]"
)
print("contains(@class, ...):")
for element in contains_matches:
print("-", element.text)
# Expected output:
# contains(@class, ...):
# - The Best Web Scraping API
# - Web Scraping API with multiple classes
# - Web Scraping API with a similar class name
# Example 2
# @class="..." matches only when the entire class attribute
# is exactly "mb-[33px]".
exact_matches = driver.find_elements(
By.XPATH,
"//h1[@class='mb-[33px]']"
)
print("\n@class='mb-[33px]':")
for element in exact_matches:
print("-", element.text)
# Expected output:
# @class='mb-[33px]':
# - The Best Web Scraping API
# Example 3
# Match "mb-[33px]" as a whole class name, even when the element
# has multiple classes. This avoids partial matches.
whole_class_matches = driver.find_elements(
By.XPATH,
'//h1[contains(concat(" ", normalize-space(@class), " "), " mb-[33px] ")]'
)
print("\nWhole class match:")
for element in whole_class_matches:
print("-", element.text)
# Expected output:
# Whole class match:
# - The Best Web Scraping API
# - Web Scraping API with multiple classes
finally:
driver.quit()
Note: The example uses different outer Python quotes ('...' and "...") to avoid escaping the quotes inside the XPath expression. Both styles are equivalent.