Zenrows
Talk to sales Start free

What is an XPath selector?

XPath is a query language for addressing parts of a document tree. It was designed for XML and works on HTML once a parser has built the tree. Where a CSS selector describes a pattern to match, an XPath expression describes a path to walk, and it can walk in directions CSS has no way to express.

What it can do that CSS cannot

Three things, and each solves a problem that comes up constantly in scraping.

Move upward. //span[@class="price"]/../.. selects the grandparent of a matching element. When the data you want has no useful identifier of its own but sits next to something that does, this is the way to reach it. CSS has no parent selector.

Match on text. //button[text()="Add to cart"] finds an element by what it says. //div[contains(text(), "In stock")] matches partially. CSS cannot inspect text content at all, which is a hard limit when a page's only stable marker is its wording.

Use axes. following-sibling, preceding, ancestor and the rest let you express relationships CSS cannot reach. //dt[text()="SKU"]/following-sibling::dd[1] pulls the value out of a definition list by its label, which is a very common shape on specification tables.

The syntax, briefly

Expression Meaning
//div every div at any depth
//div[@class="price"] by attribute value
//div[contains(@class,"price")] attribute contains
//a/@href the attribute value itself
(//p)[1] the first match, one-indexed
//li[last()] the last sibling

Two things trip people up. XPath indexes from one, not zero. And //div[1] does not mean the first div on the page: it means every div that is the first among its siblings. Wrap the expression in parentheses to index the result set.

When to reach for it

Use CSS by default. It is shorter, more readable, and every parser supports it. Reach for XPath when you need a parent, when you need to match on text, or when the only stable anchor on the page is a label next to the value you want.

Mixing the two in one project is normal and sensible. The comparison on the blog goes into the tradeoff in more depth, and the XPath scraping guide works through practical expressions.

One caution: XPath matching on visible text is tied to the site's wording, so a copy change breaks it as surely as a redesign breaks a class-based selector. It is not more durable, only differently fragile.

Where Zenrows fits

The CSS Extractor accepts XPath expressions as well as CSS in the same parameter, so a page needing a parent traversal or a text match does not need a different tool. The advanced selector examples cover tables, lists and nested layouts, which is where XPath usually earns its extra verbosity.

Go deeper on the blog

In the docs

Last updated: Aug 16, 2026

Get reliable web data in minutes.

Free plan, 5,000 credits every month, no credit card required.