HTML Parsing in Swift (iOS/macOS) with SwiftSoup
When developing applications for iOS and macOS, there is often a need to extract data from web pages. Unlike Python with its powerful libraries BeautifulSoup and Scrapy, the Swift world lacked a convenient tool for HTML parsing for a long time. The solution came with the SwiftSoup library — a pure Swift port of the popular Java library Jsoup. It provides a convenient API for working with HTML documents, navigating the DOM tree, searching for elements using CSS selectors, and extracting data.
What is SwiftSoup?
SwiftSoup is an open-source library that allows you to parse HTML, extract and modify data, and clean HTML from potentially dangerous elements. It works on all Apple platforms: iOS, macOS, tvOS, watchOS. Main features:
- Parsing HTML from a string, URL, or file
- Navigating the DOM tree using CSS selectors
- Extracting text, attributes, and HTML code of elements
- Modifying the document (adding, deleting, changing elements)
- Cleaning HTML from XSS attacks
- Support for all modern HTML standards
Installing SwiftSoup
The easiest way to install is via Swift Package Manager. Add the dependency to your Package.swift file:
// 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"]) ])If you are using Xcode, open the menu File → Add Packages..., paste the repository URL, and click Add Package.
Basic HTML Parsing Example
Let's look at a simple example — extracting the page title:
import SwiftSoup
let html = "<html><head><title>PythonLib - tools for developers</title></head><body><p>Hello, world!</p></body></html>"
do { let doc = try SwiftSoup.parse(html) let title = try doc.title() print("Title: \\(title)") let bodyText = try doc.body()?.text() print("Body text: \\(bodyText ?? "")")} catch Exception.Error(let type, let message) { print("Error: \\(type) — \\(message)")} catch { print("Unknown error")}Console output:
Title: PythonLib - tools for developersBody text: Hello, world!Searching for Elements with CSS Selectors
One of the strong points of SwiftSoup is its powerful selectors, familiar to web developers. You can use any CSS selectors:
let html = """<div class="articles"> <article id="post-1"> <h2 class="title">SwiftSoup tutorial</h2> <p class="meta">Published: 2024-01-15</p> <p>Article content...</p> </article> <article id="post-2"> <h2 class="title">HTML Parsing in Swift</h2> <p class="meta">Published: 2024-02-20</p> <p>More content...</p> </article></div>"""
let doc = try SwiftSoup.parse(html)
// Search by classlet titles = try doc.select(".title")for title in titles { print(try title.text())}
// Search by IDif let post = try doc.select("#post-1").first() { let h2 = try post.select("h2").text() let date = try post.select(".meta").text() print("Article: \\(h2) — \\(date)")}
// Combined selectorlet articles = try doc.select("div.articles > article")