Парсинг HTML в Swift (iOS/macOS) с помощью SwiftSoup
При разработке приложений под iOS и macOS часто возникает необходимость извлечь данные из веб-страниц. В отличие от Python с его мощными библиотеками BeautifulSoup и Scrapy, в мире Swift долгое время не было удобного инструмента для парсинга HTML. Решением стала библиотека SwiftSoup — чистый Swift-порт популярной Java-библиотеки Jsoup. Она предоставляет удобный API для работы с HTML-документами, навигации по DOM-дереву, поиска элементов по CSS-селекторам и извлечения данных.
Что такое SwiftSoup?
SwiftSoup — это библиотека с открытым исходным кодом, которая позволяет парсить HTML, извлекать и изменять данные, а также выполнять очистку HTML от потенциально опасных элементов. Она работает на всех платформах Apple: iOS, macOS, tvOS, watchOS. Основные возможности:
- Парсинг HTML из строки, URL или файла
- Навигация по DOM-дереву с помощью CSS-селекторов
- Извлечение текста, атрибутов и HTML-кода элементов
- Модификация документа (добавление, удаление, изменение элементов)
- Очистка HTML от XSS-атак
- Поддержка всех современных стандартов HTML
Установка SwiftSoup
Самый простой способ установки — через Swift Package Manager. Добавьте зависимость в файл Package.swift:
// swift-tools-version:5.5
import PackageDescription
let package = Package(
name: "MyProject",
dependencies: [
.package(url: "https://github.com/scinfu/SwiftSoup.git", from: "2.6.0")
],
targets: [
.target(
name: "MyProject",
dependencies: ["SwiftSoup"])
]
)
Если вы используете Xcode, откройте меню File → Add Packages..., вставьте URL репозитория и нажмите Add Package.
Базовый пример парсинга HTML
Рассмотрим простейший пример — извлечение заголовка страницы:
import SwiftSoup
let html = "<html><head><title>PythonLib - инструменты для разработчиков</title></head><body><p>Привет, мир!</p></body></html>"
do {
let doc = try SwiftSoup.parse(html)
let title = try doc.title()
print("Заголовок: \(title)")
let bodyText = try doc.body()?.text()
print("Текст body: \(bodyText ?? "")")
} catch Exception.Error(let type, let message) {
print("Ошибка: \(type) — \(message)")
} catch {
print("Неизвестная ошибка")
}
Вывод в консоль:
Заголовок: PythonLib - инструменты для разработчиков
Текст body: Привет, мир!
Поиск элементов с помощью CSS-селекторов
Одна из сильных сторон SwiftSoup — мощные селекторы, знакомые веб-разработчикам. Вы можете использовать любые CSS-селекторы:
let html = """
<div class="articles">
<article id="post-1">
<h2 class="title">SwiftSoup tutorial</h2>
<p class="meta">Опубликовано: 2024-01-15</p>
<p>Содержание статьи...</p>
</article>
<article id="post-2">
<h2 class="title">Парсинг HTML на Swift</h2>
<p class="meta">Опубликовано: 2024-02-20</p>
<p>Ещё одно содержание...</p>
</article>
</div>
"""
let doc = try SwiftSoup.parse(html)
// Поиск по классу
let titles = try doc.select(".title")
for title in titles {
print(try title.text())
}
// Поиск по ID
if let post = try doc.select("#post-1").first() {
let h2 = try post.select("h2").text()
let date = try post.select(".meta").text()
print("Статья: \(h2) — \(date)")
}
// Комбинированный селектор
let articles = try doc.select("div.articles > article")
print("Найдено статей: \(articles.count)")
Извлечение атрибутов и ссылок
Часто требуется получить не только текст, но и значения атрибутов, например, URL ссылок или изображений:
let html = """
<ul>
<li><a href="/page1" class="link">Страница 1</a></li>
<li><a Также в библиотеке
Работа с Markdown в TypeScript: библиотеки, парсеры и инструменты
Nodemailer — отправка email на TypeScript
Dependency Injection контейнеры в Rust: обзор и реализация на примере «dicy»
Rate Limiting в C# (.NET): руководство по библиотеке System.Threading.RateLimiting
JSON обработка в PHP: функции, примеры и best practices