How do you use XPath to find an element that contains specific text?
To match an element by partial text in XPath, use contains(). //button[contains(text(), 'Submit')] selects any button whose direct text node includes “Submit”. When the element has nested tags (a <span> inside the button, an icon, bold text), replace text() with .:
//button[contains(., 'Submit')]This matches against the full string value including descendants.
Matching by text() vs dot
text() returns the direct text children of an element, not its full visible string value. Once markup splits the label, the predicate misses the nested part:
//button[contains(text(), 'Buy now')]That fails on <button>Buy <span>now</span></button> because the direct text node is just "Buy ". Switch to ., which is the concatenated string of the element and all descendants:
//button[contains(., 'Buy now')]If whitespace or line breaks split the label, wrap it: contains(normalize-space(.), 'Buy now'). Default to . (or normalize-space(.)) unless you know the element has a single clean text node.
Matching by attribute
The same contains() shape works against any attribute:
//input[contains(@class, 'user-input')]Swap @class for @id, @href, @aria-label, or any @data-* attribute. Visible text changes with copy edits, A/B tests, and localization, so attribute selectors usually survive deploys longer than text selectors.
Combining conditions
When one contains() matches too many nodes, narrow with and:
//div[contains(@class, 'alert') and contains(., 'successfully')]Use or as a fallback when the same label can live in either visible text or an aria-label: //button[contains(., 'Submit') or contains(@aria-label, 'Submit')].
Related articles
All articles →How to Select Elements By Text in XPath?
XPath text matching that survives real markup. On live pages contains(.) found the element in 98% of cases, text() forms in 67-69%. This guide shows why.
Web Scraping with XPath in Selenium
Using XPath in Selenium for scraping helps to parse dynamic elements and to find element at any level of DOM structure.
XPath vs CSS: Why Web Scrapers Should Stop Listening to QA Testers
Use CSS selectors for browser clicks, XPath for extraction. Python benchmarks: lxml XPath beats CSS 2x on direct paths, and one extra // costs 570x.
Run XPath against pages that actually loaded
HasData fetches blocked, rendered, or protected pages, so XPath has something to query.