What Is Selectolax? β Definition and How It Works
Learn what selectolax is, why it is the fastest Python HTML parser, and what you give up for that speed.
Selectolax is a Python binding for the Modest and Lexbor HTML parsers written in C. It is the fastest practical way to parse HTML in Python, at the cost of a deliberately minimal API.
1. The API Is Small On Purpose
from selectolax.lexbor import LexborHTMLParser
tree = LexborHTMLParser(page_html)
for card in tree.css("div.product-card"):
title = card.css_first("h2.title")
price = card.css_first("span.price")
link = card.css_first("a[href]")
print(
title.text(strip=True) if title else None,
price.text(strip=True) if price else None,
link.attributes.get("href") if link else None,
)
css returns a list, css_first returns a node or None. The explicit None checks are not boilerplate you can avoid β they are the API telling you a missing element is a normal outcome.
2. Why It Is Fast
Parsing happens entirely in C with a parser written for speed, and the Python layer is a thin wrapper that avoids constructing rich objects for every node.
The consequence in a pipeline: on large HTML documents processed at volume, parsing time drops far enough that it stops being the dominant cost, and extraction logic or I/O becomes the bottleneck instead.
3. What You Give Up
| Feature | selectolax |
|---|---|
| CSS selectors | Yes |
| XPath | No |
| Tree modification | Limited |
| Pretty printing | No |
| Rich traversal API | Minimal |
| Encoding detection | Basic |
The absence of XPath is the decisive limitation. Label-to-value extraction β find the dt with this text, take the next dd β is natural in XPath and has no clean CSS equivalent, so those cases need manual sibling walking or a different parser.
4. Two Backends
selectolax.parser.HTMLParser wraps Modest; selectolax.lexbor.LexborHTMLParser wraps Lexbor.
Lexbor is the newer, more actively developed engine with better HTML5 conformance, and is the reasonable default. Their APIs are close enough that switching is usually a change of import.
5. When It Is the Right Choice
High-volume parsing of similar pages, where the selectors are known and simple, and throughput is the constraint.
Memory-constrained environments, since it holds a lighter representation than object-per-node parsers.
A first-pass filter, cheaply checking whether a page is worth parsing properly before handing it to something richer.
6. When It Is Not
Exploratory work. A richer traversal API is worth far more than speed while you are still discovering a page's structure.
Complex relationships. Anything needing parent axes, sibling-after-label patterns, or text predicates.
Tree manipulation. Selectolax reads well and edits poorly.
One-off scripts. The speed advantage is irrelevant on a hundred pages, and the terser API costs you time.
7. Compared With the Alternatives
| Library | Relative speed | Selectors | API richness |
|---|---|---|---|
| selectolax (Lexbor) | Fastest | CSS | Minimal |
| lxml | Very fast | CSS and XPath | Moderate |
| BeautifulSoup + lxml | Moderate | CSS plus Python API | Rich |
| BeautifulSoup + html.parser | Slowest | CSS | Rich |
A sensible pattern is mixed: selectolax for the high-volume path where selectors are settled, lxml for the pages needing XPath, and BeautifulSoup while working out what the selectors should be.
8. Summary
Selectolax binds the C parsers Modest and Lexbor to give Python the fastest available HTML parsing, with a minimal CSS-only API and explicit None returns for missing nodes.
Choose it for high-volume parsing with settled selectors, and reach for lxml instead when you need XPath β because label-to-value and parent-axis extraction have no clean CSS equivalent.