Análise de HTML em Rust: visão geral das ferramentas e exemplos práticos
Rust é uma linguagem de programação de sistemas moderna, cada vez mais usada para criar web scrapers e analisadores de alto desempenho. Graças ao seu sistema de tipos rigoroso, segurança de memória e capacidades assíncronas, Rust é ideal para tarefas que exigem extração rápida e confiável de dados de documentos HTML. Neste artigo, veremos as principais bibliotecas para análise de HTML em Rust, suas características e forneceremos exemplos de código funcionais.
Principais bibliotecas para análise de HTML em Rust
O ecossistema Rust oferece várias soluções maduras para trabalhar com HTML. As mais populares são:
- scraper — biblioteca de alto nível com suporte a seletores CSS, construída sobre
select.rsehtml5ever. - select.rs — biblioteca para extrair dados do DOM usando seletores CSS.
- html5ever — analisador de baixo nível, compatível com o padrão HTML5 (usado internamente no Servo).
- quick-xml — analisador rápido de XML/HTML baseado em leitura de fluxo, adequado para tarefas simples.
Para a maioria das tarefas de web scraping, recomenda-se scraper, pois oferece uma API conveniente e suporte ativo da comunidade.
Instalação e configuração
Adicione a dependência ao arquivo Cargo.toml:
[dependencies]scraper = "0.20"reqwest = { version = "0.12", features = ["blocking"] }A biblioteca reqwest é usada para requisições HTTP. Se preferir uma abordagem assíncrona, use reqwest com tokio.
Exemplo 1: Extraindo títulos da página
Vamos escrever um analisador simples que obtém o título <title> e todos os cabeçalhos <h1> de uma página web:
use scraper::{Html, Selector};
fn main() -> Result<(), Box<dyn std::error::Error>> { let html = r#" <html> <head><title>Exemplo de página</title></head> <body> <h1>Primeiro cabeçalho</h1> <h1>Segundo cabeçalho</h1> </body> </html> "#;
let document = Html::parse_document(html);
// Extrai o título let title_selector = Selector::parse("title").unwrap(); if let Some(title_element) = document.select(&title_selector).next() { let title_text = title_element.text().collect::().join(""); println!("Título da página: {}", title_text); }
// Extrai todos os h1 let h1_selector = Selector::parse("h1").unwrap(); for element in document.select(&h1_selector) { let text = element.text().collect::().join(""); println!("H1: {}", text); }
Ok(())} Neste exemplo, analisamos HTML estático. Para sites reais, o HTML geralmente é obtido através de uma requisição HTTP.
Exemplo 2: Analisando um site real com requisição HTTP
Agora, usamos reqwest para carregar a página e extrair links:
use scraper::{Html, Selector};
fn main() -> Result<(), Box<dyn std::error::Error>> { let response = reqwest::blocking::get("https://www.rust-lang.org")?; let html = response.text()?;
let document = Html::parse_document(&html); let link_selector = Selector::parse("a[href]").unwrap();
println!("Links na página:"); for link in document.select(&link_selector) { if let Some(href) = link.value().attr("href") { let text = link.text().collect::(); println!(" Texto: '{}' -> URL: {}", text.trim(), href); } }
Ok(())} Observe o método attr("href") — ele permite obter o valor
Também na biblioteca
Cliente OAuth para C# (.NET): implementação de autorização através de serviços terceiros
Bean Validation (Jakarta Validation) — Validação de dados em Java
Autorização e Autenticação em JavaScript (Node.js): guia completo
NodaTime para C# (.NET): guia completo com exemplos práticos
ORM para TypeScript: comparação entre TypeORM, Prisma e MikroORM