You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中用SwiftSoup解析HTML到结构体并打印内容的方法

解决ASPX登录VIEWSTATE参数解析与打印问题

问题根源

现有代码存在两个核心问题:

  • NetworkingManager的request方法是异步执行的,解析出的viewstateToken仅存在于网络请求闭包内部,没有对外传递的渠道,导致ContentView无法获取并打印;
  • 结构体默认没有友好的打印格式,直接print无法清晰展示参数内容。

解决方案

1. 给NetworkingManager添加回调闭包

修改request方法,新增completion回调来传递解析结果(成功返回viewstateToken,失败返回错误):

final class NetworkingManager {
    
    static let shared = NetworkingManager()
  
    private init() {}
    
    func request(_ absoluteURL: String, completion: @escaping (Result<viewstateToken, Error>) -> Void) {
        guard let url = URL(string: absoluteURL) else {
            completion(.failure(NSError(domain: "无效URL", code: -1, userInfo: nil)))
            return
        }
        let request = URLRequest(url: url)
        
        let dataTask = URLSession.shared.dataTask(with: request) { data, response, error in
            if let error = error {
                completion(.failure(error))
                return
            }
            
            guard let response = response as? HTTPURLResponse,
                  (200...300) ~= response.statusCode else {
                completion(.failure(NSError(domain: "HTTP响应异常", code: -2, userInfo: nil)))
                return
            }
            
            guard let data = data, let tempHTML = String(data: data, encoding: .utf8) else {
                completion(.failure(NSError(domain: "数据解析失败", code: -3, userInfo: nil)))
                return
            }
            
            do {
                let htmlDocument = try SwiftSoup.parse(tempHTML)
                // 避免重复解析HTML,提升效率
                let viewState = try htmlDocument.select("input[name=__VIEWSTATE]").attr("value")
                let viewStateGenerator = try htmlDocument.select("input[name=__VIEWSTATEGENERATOR]").attr("value")
                
                let tokens = viewstateToken(viewState: viewState, viewStateGenerator: viewStateGenerator)
                completion(.success(tokens))
                
            } catch {
                completion(.failure(error))
            }
           
        }
        dataTask.resume()
    }
}

2. 让viewstateToken支持友好打印

给结构体添加CustomStringConvertible协议,自定义打印格式:

struct viewstateToken: Identifiable, Hashable, Codable, CustomStringConvertible {
    let id = UUID()
    var viewState: String
    var viewStateGenerator: String
    
    var description: String {
        return "viewstateToken:\n  viewState: \(viewState)\n  viewStateGenerator: \(viewStateGenerator)\n  id: \(id)"
    }
}

3. 在ContentView中获取并打印tokens

修改onAppear中的调用逻辑,通过回调拿到结果并打印:

.onAppear {
    NetworkingManager.shared.request("https://examplelink.com") { result in
        switch result {
        case .success(let tokens):
            print(tokens) // 现在可以打印清晰的结构体内容
        case .failure(let error):
            print("请求或解析错误:\(error)")
        }
    }
}

额外优化点

  • 替换了原代码中的强制解包(try!、url!),改为安全的可选绑定和错误处理,避免运行时崩溃;
  • 只解析一次HTML文档,提升性能;
  • 统一错误处理逻辑,通过回调返回所有可能的错误类型。

内容的提问来源于stack exchange,提问作者Sander

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 22:43:12