Парсинг HTML в Rust: библиотеки, инструменты и примеры кода

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Парсинг HTML в Rust: обзор библиотек и практические примеры

Rust — язык системного программирования, который набирает популярность в задачах веб-скрапинга и парсинга HTML благодаря своей производительности, безопасности памяти и строгой типизации. В этой статье мы рассмотрим основные библиотеки для парсинга HTML в Rust, их возможности и приведём примеры кода для каждой из них.

1. Библиотека scraper

scraper — одна из самых популярных и удобных библиотек для парсинга HTML в Rust. Она построена на основе html5ever (парсер HTML5) и предоставляет высокоуровневый API для навигации по DOM-дереву с помощью CSS-селекторов.

Установка

[dependencies]
scraper = "0.19"

Пример: получение заголовков статей

use scraper::{Html, Selector};

fn main() {
    let html = r#"
        <html>
            <body>
                <h1 class="title">Первая статья</h1>
                <h1 class="title">Вторая статья</h1>
            </body>
        </html>
    "#;

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

    for element in document.select(&selector) {
        println!("{}", element.text().collect::<Vec<_>>().join(" "));
    }
}

Преимущества:

  • Интуитивный API для CSS-селекторов
  • Поддержка всех стандартных псевдоклассов и комбинаторов
  • Высокая производительность
  • Хорошая документация

2. Библиотека select.rs

select.rs — ещё одна мощная библиотека для парсинга HTML, основанная на html5ever. Она предлагает API, похожий на jQuery, что делает её особенно удобной для разработчиков, знакомых с JavaScript.

Установка

[dependencies]
select = "0.6"

Пример: извлечение ссылок

use select::document::Document;
use select::predicate::{Name, Class};

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

    let document = Document::from(html);

    for node in document.find(Class("link")) {
        if let Some(href) = node.attr("href") {
            println!("Ссылка: {}", href);
        }
    }
}

Преимущества:

  • jQuery-подобный синтаксис
  • Гибкие предикаты для поиска элементов
  • Поддержка атрибутов и текстового содержимого

3. Библиотека html5ever

html5ever — низкоуровневый парсер HTML5, написанный на Rust. Он является основой для многих других библиотек (включая scraper и select.rs). Если вам нужен полный контроль над процессом парсинга, это отличный выбор.

Установка

[dependencies]
html5ever = "0.27"

Пример: токенизация HTML

use html5ever::tendril::TendrilSink;
use html5ever::parse_document;
use html5ever::rcdom::{RcDom, Handle, NodeData};

fn main() {
    let html = "<p>Hello, Rust!</p>";
    let dom = parse_document(RcDom::default(), Default::default())
        .from_utf8()
        .read_from(&mut html.as_bytes())
        .unwrap();

    // Обход DOM-дерева
    fn walk(node: &Handle, depth: usize) {
        match node.data {
            NodeData::Text { ref contents } => {
                let text = contents.borrow();
                println!("{:indent$}Текст: {}", "", text, indent = depth * 2);
            }
            NodeData::Element { ref name, .. } => {
                println!("{:indent$}Элемент: {}", "", name.local, indent = depth * 2);
            }
            _ => {}
        }
        for child in node.children.borrow().iter() {
            walk(child, depth + 1);
        }
    }

    walk(&dom.document, 0);
}

Преимущества:

  • Соответствие стандарту HTML5
  • Высокая скорость работы
  • Возможность кастомной

Рекомендаций