Стендап Сьогодні 📢 Канал в Telegram @stendap_sogodni
🤖🚫 AI-free content. This post is 100% written by a human, as is everything on my blog. Enjoy!12.04.2023
Парсинг та обробка HTML в Go
Якщо в Go доведеться парсити HTML, то для того є непоганий офіційний пакет golang.org/x/net/html. Він здійснює потокову обробку документа; тобто ніякого DOM-дерева не будує, а замість того пропонує пройтись по документу циклом та відреагувати на всі потрібні елементи. Це дуже відрізняється від роботи з HTML у JavaScript та від культової бібліотеки Nokogiri для Ruby.
Сучасні вебінженери звикли бачити HTML як дерево, та адресувати це дерево селекторами CSS: div#header a.nav-link
. Це просто в розумінні, але складно алгоритмічно: бо потребує спочатку побудови дерева, а потім ще й пошуку по ньому.
Натомість при потоковій обробці ми маємо заздалегідь запланувати, що хочемо отримати з документа, та власноруч стежити за станом обробки. Наприклад, коли зустрінемо тег div
, то перевіримо, чи є в нього атрибут id==header
, та якщо є, увімкнемо змінну inHeader = true
. А коли зустрінемо тег a
, то перевіримо, чи увімкнена змінна inHeader
, та якщо так, запишемо в масив navLinks
.
Якщо ми хочемо отримати з документа не єдиний “селектор”, а декілька, то стану стає багато, та відстежити що до чого стає складніше. Тому потокова обробка тільки для особливо вибагливих до швидкодії випадків.
Але є ситуація, де потокова обробка прямо набагато краще. Це коли документ ми змінюємо. Річ у тім, що розбір документа в дерево — операція зазвичай незворотна; вона втрачає нюанси форматування, та особливо — помилки синтаксису. А з таким неформатним форматом як HTML, помилка синтаксису цілком може бути помилкою тільки для даного парсера — та її “виправлення” навпаки документ поламає (прибере “неправильний” тег, наприклад). Тому й варто нічого не міняти без потреби.
З потоковою обробкою оригінальний зміст документа не втрачається; те, що нам не цікаво, ми просто копіюємо у вихідний документ — байт в байт. А зміни можна робити як на рівні блоків, так і на рівні тегів або навіть атрибутів — як забажаємо.