Symfony DomCrawler
A PHP component for navigating, filtering, and extracting data from HTML and XML documents.
Repository Health
Technical Analysis
The DomCrawler component wraps PHP’s native DOM extension with an ergonomic, chainable API for walking HTML and XML documents. Its Crawler class parses a document (or accepts an existing DOMDocument/DOMNodeList) and lets you filter nodes with CSS selectors (via the companion symfony/css-selector component) or raw XPath, then extract text, attributes, or navigate to parent/sibling/child nodes — all while returning a new Crawler instance so calls can be chained.
Beyond read-only traversal, it models HTML forms (Form, FormFieldRegistry) and links (Link, Image) as first-class objects, so a scraper or functional test can select a <form>, fill its fields, and read back the resulting request parameters without hand-parsing the markup. It’s a foundational piece of the Symfony ecosystem — used directly by symfony/browser-kit and Symfony’s functional-testing stack (WebTestCase), and widely reused standalone in scraping and HTML-processing tools outside of full Symfony applications.
What You Get
- A
Crawlerclass that parses HTML/XML strings (or wraps existingDOMDocument/DOMNodeListinstances) and supports CSS-selector filtering (viasymfony/css-selector) or raw XPath queries - Chainable traversal methods (
filter(),filterXPath(),eq(),first(),last(),parents(),siblings(),children()) that each return a newCrawler - Extraction helpers (
text(),attr(),extract(),html()) for pulling data out of matched nodes without manual DOM API calls - First-class
FormandFormFieldRegistryobjects that let you select a form, set field values, and read back submission data as an array LinkandImagevalue objects for extracting anchor/image URIs, plusUriResolverfor resolving relative URIs against a base
Common Use Cases
- Functional/integration testing of web applications — Symfony’s
WebTestCaseuses DomCrawler under the hood to let tests assert on rendered HTML and submit forms - Web scraping and HTML data extraction tools that need reliable CSS-selector/XPath querying without hand-rolling DOM traversal
- Static site or content pipelines that need to parse and transform HTML fragments (e.g., extracting all links or images from a rendered page)
- Browser-automation-adjacent tooling (paired with
symfony/browser-kit) for headless HTTP-based crawling and form submission
Under The Hood
Architecture — The core Crawler class (Crawler.php, ~1,217 lines) implements \Countable and \IteratorAggregate over a collection of \DOMNode objects. Filtering methods (filter(), filterXPath()) translate CSS selectors into XPath via an injected CssSelectorConverter (from symfony/css-selector, an optional dev/runtime dependency) and run them against the wrapped nodes, always returning a fresh immutable-feeling Crawler instance rather than mutating in place. Form handling is split into Form (represents a single <form> and orchestrates its fields) and FormFieldRegistry (indexes fields by name, handling PHP’s array-style field naming like field[]), while Link/Image/AbstractUriElement model anchor and image elements with UriResolver handling relative-to-absolute URI resolution.
Tech Stack — Pure PHP (>=8.4.1 for this HEAD version) built directly on ext-dom, with symfony/polyfill-ctype and symfony/polyfill-mbstring as the only hard runtime dependencies and symfony/css-selector as an optional dev dependency for CSS-selector support. No external HTTP client is bundled — DomCrawler only parses/traverses markup you hand it, leaving fetching to symfony/browser-kit or any HTTP client.
Code Quality — 17 test files under Tests/ cover the Crawler, Form, FormFieldRegistry, Link, Image, and UriResolver classes; as a core Symfony component it follows Symfony’s strict internal coding standards, uses typed properties throughout, and carries a CHANGELOG documenting behavior changes release-over-release — commit activity of ~3.7/month reflects steady maintenance rather than heavy churn for a mature, feature-complete component.
API Design — The fluent, chainable design ($crawler->filter('.item')->each(fn ($node) => $node->text())) mirrors jQuery-style DOM traversal, which makes it immediately familiar to anyone who has done client-side DOM work, and the form/link abstractions remove the need to hand-write markup parsing for the two most common scraping/testing needs (reading forms, following links).
Used by 4 apps in this directory
Craft CMS
CMS
A developer-first PHP CMS with clean-slate content modeling, auto-generated GraphQL API, and a four-tier edition system that scales from solo projects to enterprise deployments.
Kimai
Invoicing Finance · Project Management
Professional open-source time tracking with invoicing, multi-user support, SAML/LDAP auth, and a full REST API—self-host it or use the cloud.
Mautic
Automation · Marketing · Ecommerce
The world's largest open source marketing automation platform — own your data, run multi-channel campaigns, and escape vendor lock-in forever.
wallabag
Bookmarks Archiving
Self-hosted read-it-later app that saves clean, ad-free articles from any webpage for distraction-free reading across all your devices.