SwiftUI中如何像浏览器一样解析网页并获取HTML DOM元素?
解决Instagram页面渲染后DOM提取的问题
为什么直接爬取拿到的是未渲染内容
Instagram是基于React的单页应用(SPA),服务器返回的初始HTML仅包含基础框架,实际页面内容是通过前端JS动态加载渲染的,所以直接用String(contentsOf:)或SwiftSoup请求,只能拿到未渲染的骨架代码。
方案一:用WebView渲染后提取DOM
这是最可靠的方式,WebView会像浏览器一样执行JS并完成页面渲染,具体步骤如下:
- 在SwiftUI中集成
WKWebView(SwiftUI原生WebView功能有限,需用UIKit的WKWebView包装) - 监听网页加载完成事件,注入JS代码获取完整DOM
- 将获取到的DOM文本回调到SwiftUI中
示例代码:
import SwiftUI import WebKit struct WebViewReader: UIViewRepresentable { let url: URL var onDOMReady: (String) -> Void func makeUIView(context: Context) -> WKWebView { let webView = WKWebView() webView.navigationDelegate = context.coordinator return webView } func updateUIView(_ uiView: WKWebView, context: Context) { uiView.load(URLRequest(url: url)) } func makeCoordinator() -> Coordinator { Coordinator(parent: self) } class Coordinator: NSObject, WKNavigationDelegate { let parent: WebViewReader init(parent: WebViewReader) { self.parent = parent } func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { // 注入JS获取完整HTML DOM webView.evaluateJavaScript("document.documentElement.outerHTML") { result, error in if let html = result as? String { self.parent.onDOMReady(html) } } } } } // 在SwiftUI视图中使用 struct ContentView: View { @State private var renderedHTML = "" var body: some View { VStack { WebViewReader(url: URL(string: "https://www.instagram.com/sasawpi/")!) { html in self.renderedHTML = html } Text(renderedHTML.prefix(500)) // 预览前500字符 } } }
方案二:调用Instagram官方Graph API(更推荐)
直接爬取渲染后的DOM容易触发反爬机制,Instagram官方提供了Graph API,通过合法的API请求可以直接获取用户、帖子等结构化数据,无需处理DOM解析。
- 需要注册Facebook开发者账号,创建应用获取API密钥
- 需遵循API的调用限制和权限要求
关于SwiftSoup的补充
SwiftSoup仅具备HTML解析能力,没有JS渲染功能,无法直接处理SPA的动态内容,必须先拿到渲染后的完整HTML,再用SwiftSoup解析提取所需内容。
内容的提问来源于stack exchange,提问作者Aramis
相关产品推荐
相关产品推荐

