En este artículo, escribí algunos pequeños programas para mostrarle cómo funciona el análisis de páginas web en Rust. Para esta tarea, elegí: bibliotecas y . Tokio, Reqwest Scraper Tokio Es una biblioteca para escribir aplicaciones confiables, asincrónicas y delgadas con el lenguaje de programación Rust. Por qué elijo Tokio: Es rápido: Tokio usa abstracciones de costo cero para asíncrono. Es seguro: Tokio usa solo Rust seguro y paralelismo basado en Rust. Es escalable: Huella mínima en su aplicación. Tokio es también una biblioteca asíncrona más popular que async-std. Eso utiliza la multitarea cooperativa basada en hilos verdes. Lista de proyectos que usan Tokio, basada en el repositorio Github de Tokio : una implementación HTTP rápida y correcta para Rust. hyper: una implementación oxidada de gRPC. tónico: un marco de servidor web componible súper fácil para velocidades warp. warp: Una biblioteca de componentes modulares y reutilizables para crear servidores y clientes de red robustos. torre: es un marco para instrumentar programas Rust para recopilar información de diagnóstico estructurada basada en eventos. seguimiento: una biblioteca de conectividad de base de datos Rust (RDBC) para MySQL, Postgres y SQLite. rdbc: biblioteca de E/S rápida y de bajo nivel para Rust que se centra en las API sin bloqueo. mio: una biblioteca de utilidades para trabajar con bytes. bytes: la herramienta de prueba para el código Rust concurrente. telar: Reqoeste Un cliente HTTP ergonómico con baterías incluidas para Rust. Características: Cuerpos sin formato, JSON, codificado en urlen, multiparte Política de redirección personalizable Proxies HTTP HTTPS a través de TLS nativo del sistema (u opcionalmente, rustls) tienda de galletas ERA M Reqwest usa Tokio para solicitudes asíncronas y tiene un modo de trabajo de bloqueo. En este artículo, utilicé el modo asíncrono. Raspador Scraper proporciona una interfaz para html5ever y cajas de selectores de Servo, para análisis y consultas de nivel de navegador. Primer programa: scrapper simple para páginas de "índice de". title .value() .to_string() ); } } use scraper::{Html, Selector}; #[tokio::main] async fn main () -> Result <(), Box < dyn std::error::Error>> { let resp = reqwest::get( "https://www.wireshark.org/download/" ). await ?; let text = resp.text(). await ?; let document = Html::parse_document(&text); let selector = Selector::parse( r#"table > tbody > tr > td > a"# ).unwrap(); for title in document.select(&selector) { println! ( "{}" , resp.url().to_string()); println! ( "{}" , .attr( "href" ) .expect( "href not found" ) Ok (()) Aquí hay una pequeña actualización para este programa. Aquí la página de Whireshark tiene enlaces duplicados. Podemos ignorarlos usando un hashmap. urls.insert(url); } } } } use scraper::{Html, Selector}; use std::collections::HashSet; #[tokio::main] async fn main () -> Result <(), Box < dyn std::error::Error>> { let resp = reqwest::get( "https://www.wireshark.org/download/" ). await ?; println! ( "{}" , resp.url().to_string()); let text = resp.text(). await ?; let mut urls:HashSet< String > = HashSet::new(); let document = Html::parse_document(&text); let selector = Selector::parse( r#"table > tbody > tr > td > a"# ).unwrap(); for title in document.select(&selector) { let url = title.value().attr( "href" ).expect( "href not found" ).to_string(); if url != "/" || url != "." || url != ".." { for url in urls{ println! ( "{}" , url); Ok (()) Para la próxima iteración, quiero mostrarles cómo hacer un analizador menos complejo, pero con más funciones. recopila nuevos fondos de pantalla del sitio web de Wallheaven. Tarea: En este sitio, puede encontrar el botón "aleatorio" que le brinda 24 imágenes aleatorias. Para esta tarea, necesitamos analizar esta página. Después de eso, vaya a la URL de la imagen, obtenga una URL de imagen de tamaño completo y descargue la imagen. } }; } } } } } }; } } } } use scraper::{Html, Selector}; use std::io::Cursor; use std::process; #[tokio::main] async fn main () -> Result <(), Box < dyn std::error::Error>> { let resp = match reqwest::get( "https://wallhaven.cc/random" ). await { Ok (x) => x, Err (_) => { println! ( "{}" , "error on /random request" ); process::exit( 0x0100 ); //exit if error expected during request to /random let text = resp.text(). await ?; let document = Html::parse_document(&text); let selector = Selector::parse( r#"ul > li > figure > a"# ).unwrap(); for elem in document.select(&selector) { let href = elem.value().attr( "href" ).expect( "href not found!" ); download(&href.to_string()). await ?; Ok (()) async fn download (url: & String ) -> Result <(), Box < dyn std::error::Error>> { let resp = reqwest::get(url). await ?; let text = resp.text(). await ?; let document = Html::parse_document(&text); let selector = Selector::parse( r#"img"# ).unwrap(); for elem in document.select(&selector) { let picture_url = elem.value().attr( "data-cfsrc" ); match picture_url { Some (x) => { // ignoring another pictures on page like logo and avatar if x.contains( "avatar" ) || x.contains( "logo" ) { continue ; // trying to get original name of picture let file_path = x.split( "/" ).last().expect( "cant find filename" ); match reqwest::get(x). await { Ok (x) => { let mut file = std::fs::File::create(file_path)?; let mut content = Cursor::new(x.bytes(). await ?); std::io::copy(& mut content, & mut file)?; println! ( "Created: {}" , file_path); Err (_) => { continue ; None => {} Ok (()) En conclusión, quiero mostrar y resolver algunas tareas prácticas de análisis sintáctico con fines educativos y refactorizados no tan bien como sea posible. Para la producción, vea mejores ejemplos y desarrolle sus propias tareas.