Parsing HTML in Swift (iOS/macOS) with SwiftSoup
When developing applications for iOS and macOS, it is often necessary to extract data from HTML pages. Whether it's parsing a news site, getting currency exchange rates, or analyzing web content, a reliable tool is essential. In the Swift world, the de facto standard is the SwiftSoup library — a pure Swift port of the popular Java parser Jsoup.
SwiftSoup provides a convenient API for loading, parsing, and manipulating HTML documents using CSS selectors and DOM traversal methods. The library is written entirely in Swift, has no external dependencies, and supports all Apple platforms: iOS (starting from 11.0), macOS (10.13+), watchOS, and tvOS.
Installing SwiftSoup via Swift Package Manager
Add the dependency to your project's Package.swift or via the Xcode menu: File → Add Packages...
// Package.swiftdependencies: [ .package(url: "https://github.com/scinfu/SwiftSoup.git", from: "2.6.0")],targets: [ .target( name: "YourTarget", dependencies: ["SwiftSoup"])]
// Or in Xcode: https://github.com/scinfu/SwiftSoup.git, version 2.6.0After installation, import the library in the desired file:
import SwiftSoupBasic Parsing of an HTML String
The simplest way to get started is to parse an HTML string obtained, for example, from URLSession:
let html = """<html> <body> <h1>Hello, world!</h1> <p class="content">This is text inside a paragraph</p> <a href="https://example.com">Link</a> </body></html>"""
do { let doc: Document = try SwiftSoup.parse(html) let title = try doc.title() let paragraph = try doc.select("p.content").first()?.text() let link = try doc.select("a").first()?.attr("href") print("Title: \\(title)") print("Paragraph: \\(paragraph ?? "not found")") print("Link: \\(link ?? "not found")")} catch { print("Parsing error: \\(error)")}Loading and Parsing HTML from the Network
Most often, HTML is obtained via HTTP. Here is an example of loading a page and extracting data:
import Foundationimport SwiftSoup
func fetchAndParse(urlString: String) async { guard let url = URL(string: urlString) else { return } do { let (data, _) = try await URLSession.shared.data(from: url) guard let html = String(data: data, encoding: .utf8) else { return } let doc = try SwiftSoup.parse(html) // Extract all links let links = try doc.select("a[href]") for link in links { let href = try link.attr("href") let text = try link.text() print("\\(text) -> \\(href)") } // Extract h2 headings let headings = try doc.select("h2") for heading in headings { print("Heading: \\(try heading.text())") } } catch { print("Error: \\(error)") }}
// UsageTask { await fetchAndParse(urlString: "https://example.com")}Working with CSS Selectors
SwiftSoup supports virtually all standard CSS selectors, making element search intuitive:
tag— by tag name:try doc.select("div")#id— by identifier:try doc.select("#main-content").class— by class:try doc.select(".article-title")[attribute]— by attribute:try doc.select("[data-id]")parent > child— direct child:try doc.select("ul > li")el:contains(t
Also in library
CLI framework for Rust: Clap — a powerful and convenient tool for creating console applications
Working with CSV in C++: Libraries, Parsing, and Data Writing
PDF Generation in Go: Library Overview and Code Examples
Working with Excel in C# (.NET): EPPlus, ClosedXML, and NPOI Libraries