Parsing de HTML em Swift (iOS/macOS) com SwiftSoup
Ao desenvolver aplicativos para iOS e macOS, muitas vezes surge a necessidade de extrair dados de páginas web. Ao contrário do Python, com suas poderosas bibliotecas BeautifulSoup e Scrapy, no mundo Swift não havia uma ferramenta conveniente para parsing de HTML por muito tempo. A solução foi a biblioteca SwiftSoup — um port puro em Swift da popular biblioteca Java Jsoup. Ela fornece uma API conveniente para trabalhar com documentos HTML, navegar pela árvore DOM, pesquisar elementos por seletores CSS e extrair dados.
O que é SwiftSoup?
SwiftSoup é uma biblioteca de código aberto que permite fazer parsing de HTML, extrair e modificar dados, além de realizar a limpeza de HTML de elementos potencialmente perigosos. Ela funciona em todas as plataformas Apple: iOS, macOS, tvOS, watchOS. Principais funcionalidades:
- Parsing de HTML a partir de string, URL ou arquivo
- Navegação pela árvore DOM usando seletores CSS
- Extração de texto, atributos e código HTML dos elementos
- Modificação do documento (adição, remoção, alteração de elementos)
- Limpeza de HTML contra ataques XSS
- Suporte a todos os padrões modernos de HTML
Instalação do SwiftSoup
A maneira mais simples de instalar é através do Swift Package Manager. Adicione a dependência no arquivo Package.swift:
// swift-tools-version:5.5import 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"]) ])Se você estiver usando o Xcode, abra o menu File → Add Packages..., cole a URL do repositório e clique em Add Package.
Exemplo básico de parsing de HTML
Vamos considerar um exemplo simples — extrair o título da página:
import SwiftSoup
let html = "<html><head><title>PythonLib - ferramentas para desenvolvedores</title></head><body><p>Olá, mundo!</p></body></html>"
do { let doc = try SwiftSoup.parse(html) let title = try doc.title() print("Título: \\(title)") let bodyText = try doc.body()?.text() print("Texto do body: \\(bodyText ?? "")")} catch Exception.Error(let type, let message) { print("Erro: \\(type) — \\(message)")} catch { print("Erro desconhecido")}Saída no console:
Título: PythonLib - ferramentas para desenvolvedoresTexto do body: Olá, mundo!Pesquisa de elementos com seletores CSS
Um dos pontos fortes do SwiftSoup são os seletores poderosos, familiares aos desenvolvedores web. Você pode usar qualquer seletor CSS:
let html = """<div class="articles"> <article id="post-1"> <h2 class="title">Tutorial SwiftSoup</h2> <p class="meta">Publicado em: 2024-01-15</p> <p>Conteúdo do artigo...</p> </article> <article id="post-2"> <h2 class="title">Parsing de HTML em Swift</h2> <p class="meta">Publicado em: 2024-02-20</p> <p>Mais um conteúdo...</p> </article></div>"""
let doc = try SwiftSoup.parse(html)
// Pesquisa por classelet titles = try doc.select(".title")for title in titles { print(try title.text())}
// Pesquisa por IDif let post = try doc.select("#post-1").first() { let h2 = try post.select("h2").text() let date = try post.select(".meta").text() print("Artigo: \\(h2) — \\(date)")}
// Seletor combinadolet articles = try doc.select("div.articles > article")