Parseo de HTML en Swift (iOS/macOS): revisión de las bibliotecas SwiftSoup y Fuzi
Al desarrollar aplicaciones para iOS y macOS, a menudo surge la necesidad de extraer datos de páginas web. El parseo de HTML permite obtener contenido automáticamente, estructurarlo y utilizarlo en la aplicación. En el ecosistema de Swift, existen varias bibliotecas potentes para estos fines. En este artículo, revisaremos en detalle las dos más populares: SwiftSoup y Fuzi. Aprenderá cómo instalarlas, cómo realizar operaciones básicas de parseo y qué características tiene cada una.
¿Por qué es necesario el parseo de HTML en Swift?
El parseo de HTML es útil en los siguientes escenarios:
- Agregación de datos — recopilación de noticias, precios, descripciones de productos de varios sitios web.
- Monitoreo de cambios — seguimiento de actualizaciones en páginas objetivo.
- Integración con servicios web — si el sitio no proporciona una API, el parseo es la única forma de obtener datos.
- Automatización de pruebas — verificación de la corrección de la estructura HTML.
Biblioteca SwiftSoup
SwiftSoup es el puerto Swift de la popular biblioteca Java Jsoup. Proporciona una API conveniente para parsear, navegar y manipular documentos HTML. SwiftSoup admite selectores CSS, lo que hace que la extracción de elementos sea simple e intuitiva.
Instalación de SwiftSoup
Agregue la dependencia en su Package.swift o a través de Swift Package Manager en Xcode:
// Package.swiftdependencies: [ .package(url: "https://github.com/scinfu/SwiftSoup.git", from: "2.6.0")]Ejemplo de uso de SwiftSoup
Consideremos un ejemplo simple: cargaremos una cadena HTML y extraeremos los encabezados <h2> y los enlaces <a>.
import SwiftSoup
func parseHTML() { let html = """ <html> <body> <h2>Título del artículo</h2> <p>Texto del párrafo.</p> <a href="https://example.com">Enlace</a> </body> </html> """ do { let doc = try SwiftSoup.parse(html) // Extraemos todos los encabezados h2 let headers = try doc.select("h2") for header in headers { print("Encabezado: \\(try header.text())") } // Extraemos todos los enlaces let links = try doc.select("a[href]") for link in links { let linkText = try link.text() let linkHref = try link.attr("href") print("Texto: \\(linkText), URL: \\(linkHref)") } } catch { print("Error de parseo: \\(error)") }}En este ejemplo, usamos el método select() con el selector CSS "h2" para seleccionar todos los encabezados de segundo nivel, y "a[href]" para seleccionar todos los enlaces con el atributo href. El método text() devuelve el contenido textual del elemento, y attr() devuelve el valor del atributo especificado.
Navegación por el árbol del documento
SwiftSoup permite moverse por el árbol DOM:
// Obtener el primer elemento h2if let firstHeader = try doc.select("h2").first() { print("Primer encabezado: \\(try firstHeader.text())")}
// Obtener el elemento padrelet parent = try firstHeader.parent()print("Padre: \\(try parent?.tagName() ?? "nil")")
// Obtener el siguiente elemento hermanolet nextSibling = try firstHeader.nextElementSibling()print("Siguiente elemento: \\(try nextSibling?.tagName() ?? "nil")")Biblioteca Fuzi
Fuzi es otra biblioteca popular para parsear HTML y XML en Swift. Está basada en libxml2 y se caracteriza por su alto rendimiento. Fuzi también admite selectores CSS y consultas XPath.