Parsing HTML in Rust: Libraries and Practical Examples

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Parsing HTML in Rust: Overview of the Best Libraries and Code Examples



Rust is a systems programming language that is increasingly used for tasks related to HTML parsing. Thanks to its high performance, strong typing, and memory safety, Rust is well-suited for creating fast and reliable web page parsers. In this article, we will look at the main libraries for parsing HTML in Rust, their capabilities, and provide practical code examples.



Why Rust for HTML Parsing?



HTML parsing is a task that requires efficient memory management and robust error handling. Rust provides:



  • Zero-cost abstractions — high execution speed
  • Safe memory management without a garbage collector
  • A powerful type system that prevents errors at compile time
  • An active community and many libraries for web scraping


Main Libraries for Parsing HTML in Rust



1. scraper — The Most Popular Library



The scraper library provides a convenient API for navigating the DOM tree using CSS selectors. It is built on top of the html5ever parser, which conforms to HTML5 standards.



Installation:

[dependencies]scraper = "0.18"


Example: Extracting all links from a page

use scraper::{Html, Selector};

fn main() { let html = r#" <html> <body> <a href="https://example.com">Example</a> <a href="https://rust-lang.org">Rust</a> </body> </html> "#;

let document = Html::parse_document(html); let selector = Selector::parse("a").unwrap();

for element in document.select(&selector) { if let Some(href) = element.value().attr("href") { println!("Link: {}", href); } }}


2. select.rs — Lightweight and Fast Selector



The select.rs library offers a minimalistic interface for working with CSS selectors. It also uses html5ever under the hood but provides lower-level access to the DOM.



Installation:

[dependencies]select = "0.6"


Example: Finding all h2 headings

use select::document::Document;use select::predicate::Name;

fn main() { let html = r#" <html> <body> <h2>Heading 1</h2> <h2>Heading 2</h2> <p>Text</p> </body> </html> "#;

let document = Document::from(html); for node in document.find(Name("h2")) { println!("Heading text: {}", node.text()); }}


3. html5ever — Low-Level Parser



html5ever is the reference HTML5 parser written in Rust. It forms the basis of most other libraries. If you need maximum control over the parsing process, use it directly.



Example: HTML tokenization

use html5ever::tendril::TendrilSink;use html5ever::parse_document;use markup5ever::{expanded_name, local_name, namespace_url, ns};

fn main() { let html = "<p>Hello, Rust!</p>"; let dom = parse_document( std::rc::Rc::new(std::cell::RefCell::new(vec![])), Default::default() ) .from_utf8() .read_from(&mut html.as_bytes()) .unwrap();}


Practical Example: Parsing a Real Website



Let's look at a complete example of parsing a news website using scraper and reqw

Recommendations