تحليل HTML في Rust: نظرة عامة على الأدوات وأمثلة عملية
Rust هي لغة برمجة نظامية حديثة، تُستخدم بشكل متزايد لإنشاء أدوات استخراج بيانات ويب عالية الأداء ومحللات. بفضل نظام الأنواع الصارم، وأمان الذاكرة، والإمكانيات غير المتزامنة، تُعد Rust مثالية للمهام التي تتطلب استخراج البيانات من مستندات HTML بسرعة وموثوقية. في هذه المقالة، سنستعرض المكتبات الرئيسية لتحليل HTML بلغة Rust، وميزاتها، ونقدم أمثلة عملية على الكود.
المكتبات الرئيسية لتحليل HTML في Rust
يقدم نظام Rust البيئي عدة حلول ناضجة للعمل مع HTML. الأكثر شيوعًا هي:
- scraper — مكتبة عالية المستوى تدعم محددات CSS، مبنية فوق
select.rsوhtml5ever. - select.rs — مكتبة لاستخراج البيانات من DOM باستخدام محددات CSS.
- html5ever — محلل منخفض المستوى متوافق مع معيار HTML5 (يُستخدم داخل Servo).
- quick-xml — محلل XML/HTML سريع يعتمد على القراءة التدفقية، مناسب للمهام البسيطة.
لمعظم مهام استخراج بيانات الويب، يُوصى باستخدام scraper لأنه يوفر واجهة برمجة تطبيقات مريحة ودعمًا نشطًا من المجتمع.
التثبيت والإعداد
أضف التبعية إلى ملف Cargo.toml:
[dependencies]scraper = "0.20"reqwest = { version = "0.12", features = ["blocking"] }تُستخدم مكتبة reqwest لطلبات HTTP. إذا كنت تفضل النهج غير المتزامن، استخدم reqwest مع tokio.
مثال 1: استخراج عناوين الصفحة
لنكتب محللًا بسيطًا يحصل على العنوان <title> وجميع العناوين <h1> من صفحة ويب:
use scraper::{Html, Selector};
fn main() -> Result<(), Box<dyn std::error::Error>> { let html = r#" <html> <head><title>صفحة مثال</title></head> <body> <h1>العنوان الأول</h1> <h1>العنوان الثاني</h1> </body> </html> "#;
let document = Html::parse_document(html);
// استخراج title 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!("عنوان الصفحة: {}", title_text); }
// استخراج جميع 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(())} في هذا المثال، نقوم بتحليل HTML ثابت. بالنسبة للمواقع الحقيقية، يتم الحصول على HTML عادةً عبر طلب HTTP.
مثال 2: تحليل موقع حقيقي مع طلب HTTP
الآن سنستخدم reqwest لتحميل الصفحة واستخراج الروابط:
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!("الروابط في الصفحة:"); for link in document.select(&link_selector) { if let Some(href) = link.value().attr("href") { let text = link.text().collect::(); println!(" النص: '{}' -> URL: {}", text.trim(), href); } }
Ok(())} لاحظ طريقة attr("href") — فهي تسمح بالحصول على قيم