Парсинг HTML в Kotlin: Полное руководство по инструментам и библиотекам
Парсинг HTML (извлечение данных из веб-страниц) — одна из ключевых задач при создании парсеров, анализаторов контента или интеграции внешних данных. В экосистеме Kotlin существует несколько мощных библиотек, которые позволяют эффективно работать с HTML. В этой статье мы подробно разберём лучшие инструменты, их особенности и приведём практические примеры кода.
1. jsoup — стандарт де-факто для парсинга HTML
jsoup — это самая популярная Java-библиотека для работы с HTML, которая отлично работает и в Kotlin. Она предоставляет удобный API для загрузки, разбора и извлечения данных из HTML-документов.
Основные возможности:
- Загрузка HTML из URL, файла или строки
- Поддержка CSS-селекторов для поиска элементов
- Очистка HTML от нежелательных тегов
- Модификация DOM-дерева
Пример использования jsoup в Kotlin:
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
fun main() {
// Загружаем HTML-документ
val doc: Document = Jsoup.connect("https://example.com").get()
// Извлекаем заголовок страницы
val title: String = doc.title()
println("Заголовок: $title")
// Ищем все ссылки на странице
val links = doc.select("a[href]")
links.forEach { link ->
val href = link.attr("href")
val text = link.text()
println("Ссылка: $text -> $href")
}
// Извлекаем текст из определенного блока
val content = doc.select("div.content").text()
println("Контент: $content")
// Работа с формами
val form = doc.select("form").first()
form?.select("input")?.forEach { input ->
println("Поле: ${input.attr("name")} = ${input.attr("value")}")
}
}
2. Ktor Client + khtml — современный Kotlin-стек
Ktor Client — это асинхронный HTTP-клиент для Kotlin, который отлично сочетается с библиотекой khtml (Kotlin HTML parser). Вместе они образуют мощный инструмент для веб-скрапинга.
Преимущества подхода:
- Нативная поддержка корутин (suspend функции)
- Асинхронная загрузка страниц
- Гибкая настройка HTTP-запросов
- Поддержка cookies, сессий и прокси
Пример с Ktor Client и khtml:
import io.ktor.client.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import kotlinx.coroutines.runBlocking
import org.jsoup.Jsoup
suspend fun fetchAndParse(url: String) {
val client = HttpClient()
try {
// Асинхронная загрузка HTML
val response: HttpResponse = client.get(url)
val html: String = response.bodyAsText()
// Парсинг с помощью jsoup
val doc = Jsoup.parse(html)
val headlines = doc.select("h2, h3").map { it.text() }
println("Заголовки на странице:")
headlines.forEach { println("- $it") }
} catch (e: Exception) {
println("Ошибка при загрузке: ${e.message}")
} finally {
client.close()
}
}
fun main() = runBlocking {
fetchAndParse("https://kotlinlang.org")
}
3. Selenium WebDriver — для динамических страниц
Если сайт активно использует JavaScript для рендеринга контента, вам понадобится Selenium WebDriver. Он запускает настоящий браузер и позволяет взаимодействовать с динамическими элементами.
Пример с Selenium в Kotlin:
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions
fun scrapeDynamicPage() {
val options = ChromeOptions().apply {
addArguments("--headless") // Режим без GUI
addArguments("--disable-gpu")
}
val driver: WebDriver = ChromeDriver(options)
try {
driver.get("https://example.com/dynamic")
// Ждём загрузки динамического контента
Thread.sleep(2000)
// Извлекаем данные
val elements = driver.findElements(By.cssSelector(".dynamic-content"))
elements.forEach { element ->
println("Элемент: ${element.text}")
}
// Скриншот для отладки
// val screenshot = (driver as TakesScreenshot).getScreenshotAs(OutputType.FILE)
} finally {
driver.quit()
}
}