Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Use this XPath 1.0 expression to match an element whose whitespace-separated class list contains the token notice:
//*[contains(concat(' ', normalize-space(@class), ' '), ' notice ')]
Replace notice with the class you need. The added spaces and normalize-space() make the test match a complete class token, so it finds notice in class="highlighted notice" but not inside noticeable. This pattern is documented in Parsel and Scrapy documentation.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →The reliable XPath class selector
HTML’s class attribute is normally a space-separated list, not a single value. Therefore, an exact attribute comparison is too narrow:
#1 Best Overall
//div[@class='notice']
That expression misses <div class="notice highlighted">. A bare substring test is too broad:
//*[contains(@class, 'notice')]
It can also match noticeable. Use the token-boundary pattern instead:
//*[contains(concat(' ', normalize-space(@class), ' '), ' notice ')]
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
normalize-space(@class) collapses runs of whitespace and removes leading or trailing whitespace. Concatenating one space on each side turns the class list into a searchable, space-delimited string; searching for ' notice ' then requires boundaries on both sides. The XPath language specification is available in the XPath 1.0 Recommendation.
Choose the element scope
Search every element
Use //* when the class may occur on any element type:
//*[contains(concat(' ', normalize-space(@class), ' '), ' notice ')]
Restrict the tag name
Use a tag test when you know the element type:
//div[contains(concat(' ', normalize-space(@class), ' '), ' notice ')]
This avoids returning a matching span, section, or another element with the same class.
Search descendants of the current node
When an API has already selected a parent node, make the XPath relative with a leading dot:
.//*[contains(concat(' ', normalize-space(@class), ' '), ' notice ')]
Without the dot, // starts from the document root in common XPath contexts and can return matches outside the selected subtree. Parsel demonstrates this distinction when chaining CSS selection with relative XPath in its usage documentation.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutePC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Rank #2
- Used Book in Good Condition
Require two or more classes
Add one token predicate for every class that must be present:
//*[contains(concat(' ', normalize-space(@class), ' '), ' notice ') and contains(concat(' ', normalize-space(@class), ' '), ' urgent ')]
This matches an element carrying both notice and urgent, regardless of their order or any additional classes. In HTML-aware selector APIs, the equivalent CSS selector is .notice.urgent; class membership is defined in terms of whitespace-separated tokens by Selectors Level 4.
Combine class matching with other predicates
Match text as well as class
For an element with the class and visible text containing “Warning,” combine predicates:
Recommended Free Tools
//*[contains(concat(' ', normalize-space(@class), ' '), ' notice ') and contains(normalize-space(.), 'Warning')]
normalize-space(.) uses the element’s descendant text. If exact text is required, use an equality predicate instead, but remember that nested markup can make the element’s string value differ from the text you see visually.
Match an attribute
For a classed link whose href contains /alerts/:
//a[contains(concat(' ', normalize-space(@class), ' '), ' notice ') and contains(@href, '/alerts/')]
Select an ancestor or child
XPath is useful when the class condition is only one part of navigation. For example, to select a notice’s parent:
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →//*[contains(concat(' ', normalize-space(@class), ' '), ' notice ')]/..
To select a button inside each notice:
//*[contains(concat(' ', normalize-space(@class), ' '), ' notice ')]//button
These navigation features are a reason to keep XPath when a simple CSS class selector is not enough.
Get the first matching element correctly
Position predicates have an important scope difference:
//li[1]selects everylithat is first among its siblings under its parent.(//li)[1]selects only the firstliin the document-wide result.
The same rule applies to a class-filtered query. First match overall:
(//*[contains(concat(' ', normalize-space(@class), ' '), ' notice ')])[1]
First matching notice under each parent context:
//*[contains(concat(' ', normalize-space(@class), ' '), ' notice ')][1]
Parsel documents this parenthesizing distinction in its selector guide.
XPath versus CSS for class lookup
If the task is only “find elements with this class” and your library supports CSS, .notice is shorter and easier to read. Two classes become .notice.urgent. Parsel recommends CSS for routine class lookup while showing XPath for subsequent extraction and navigation; Scrapy documents the same class-token pitfall and CSS alternative in its selector documentation.
| Need | Preferred expression | Reason |
|---|---|---|
| One class, CSS supported | .notice |
Concise token-aware class selection |
| One class, XPath required | //*[contains(concat(' ', normalize-space(@class), ' '), ' notice ')] |
Works with multiple classes and avoids substring matches |
| Two classes | .notice.urgent or two XPath predicates |
Requires both tokens |
| Class plus text, parent, or positional logic | XPath | Supports predicates and document navigation in one expression |
| Already scoped to a node | .//*[...] |
Keeps the search relative to that node |
Browser automation APIs expose XPath as one locator strategy among others; Selenium’s locator documentation provides the relevant browser context at selenium.dev.
Use the expression in host code
Python with lxml
Pass the XPath as a normal Python string. The quotes surrounding the class token must survive unchanged:
from lxml import html
tree = html.fromstring('<div class="highlighted notice">Alert</div>')
nodes = tree.xpath("//*[contains(concat(' ', normalize-space(@class), ' '), ' notice ')]")
print(nodes[0].text)
If the class name is supplied by a user or configuration, interpolate it only after applying the quoting rules of your XPath library; do not concatenate untrusted text into an expression without that library’s escaping mechanism.
Browser DevTools
In a browser console, XPath evaluation depends on the host API. The standard DOM method is:
document.evaluate("//*[contains(concat(' ', normalize-space(@class), ' '), ' notice ')]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)
Use the returned snapshot’s snapshotItem(index) method to inspect matches. Browser rendering, JavaScript execution, and namespaces are host concerns; XPath only queries the document supplied to it.
Free tools Windows power users keep installed
One-click scans. No signup required.
Scrapy or Parsel
With a response selector, use:
response.xpath("//*[contains(concat(' ', normalize-space(@class), ' '), ' notice ')]")
After a CSS selection, keep the XPath relative:
response.css('article').xpath(".//*[contains(concat(' ', normalize-space(@class), ' '), ' notice ')]")
Common failures and fixes
No results from @class='notice'
Cause: the element has additional classes, different whitespace, or a different class order.
Fix: use the padded normalize-space() token expression.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitchesUnexpected results from contains(@class, 'notice')
Cause: substring matching also sees names such as noticeable.
Fix: include the surrounding spaces in both the normalized attribute and search token.
A relative query returns elements elsewhere
Cause: the expression starts with // instead of .// after a scoped selection.
Fix: add the leading dot for descendants of the current context node.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →The “first” result is repeated
Cause: [1] was applied to each parent-level step.
Fix: wrap the complete result in parentheses before applying [1].
Best Value
The selector works in one document but not another
Cause: class values, namespaces, parser behavior, or generated DOM content differ. XPath does not fetch or render a page.
Fix: inspect the actual parsed document, confirm the class attribute exists at query time, and account for namespaces when querying XML or namespaced HTML.
Or skip the browser setup
If you need a clean screenshot of a page while diagnosing or documenting class-based elements, ScreenshotNeo returns a PNG, JPEG, WebP, or PDF from one GET request. Its cleanup steps accept cookie or consent banners and remove more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →cURL:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
See the ScreenshotNeo documentation for options such as full-page capture, CSS-selector element capture, device presets, custom JavaScript, waits, headers, cookies, blocking rules, caching, signed links, asynchronous jobs, webhooks, bulk capture, and PDF settings. The Free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
Practical checklist
- Use token-aware matching with
concat,normalize-space, and padded spaces. - Choose
//*for any tag or a specific tag such as//divwhen appropriate. - Use
.//for descendants of the current context node. - Add one predicate per required class.
- Parenthesize the full result before applying a document-wide positional predicate.
- Prefer CSS for simple class-only selection when your API supports it; retain XPath for text, navigation, and compound predicates.
- Verify the document and timing supplied by the host parser or browser.
Frequently Asked Questions
Does XPath have a dedicated class selector?
XPath has no CSS-style class shorthand. Match the class attribute as a whitespace-separated token with the padded `normalize-space()` expression.
Can this pattern match a class containing a space?
No. HTML class names are whitespace-separated tokens, so a value containing a space represents multiple classes. Match each token separately.
Why does my XPath return nothing after a CSS selection?
The XPath is probably document-rooted. Prefix the descendant expression with `.` so it is evaluated relative to the node selected by CSS.
When should I use CSS instead of XPath?
Use CSS for straightforward class membership when supported. Use XPath when you also need text predicates, ancestor/child navigation, or positional logic.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

