我正在寻找最直接的方法来从页面获取完整的 html。页面加载后,JS 完成工作后。
速度并不重要。优化并不重要。主线程的锁定并不重要。
我尝试使用 WKWebView 获取 html:
class InternetLoader {
private let webView = WKWebView(frame: .zero)
private let script = """
window.onload = function() {
document.body.innerHTML;
};
"""
private var resultHtml: String? = nil
func getHTML(from url: URL) -> String {
webView.load(URLRequest(url: url))
let semaphore = DispatchSemaphore(value: 0)
webView.evaluateJavaScript(script) { (result, error) in
if let error = error {
print("Error executing JavaScript: \(error.localizedDescription)")
} else if let htmlContent = result as? String {
self.resultHtml = htmlContent
}
semaphore.signal()
}
semaphore.wait()
return resultHtml!
}
}
用途:
let il = InternetLoader()
let html = il.getHTML(from: URL(string: "https://stackoverflow.com/questions"))
但它无休止地卡住了。
我做错了什么?
感谢命令行中的wkwebview。修改此以获得html
@MainActor
class InternetLoader: NSObject {
lazy var webView: WKWebView = {
let webView: WKWebView = WKWebView()
webView.navigationDelegate = self
return webView
}()
private var resultHtml: String? = nil
var continuation: UnsafeContinuation<String?, Error>?
func getHTML(from url: URL) async throws -> String? {
return try await withUnsafeThrowingContinuation { continuation in
self.continuation = continuation
webView.load(URLRequest(url: url))
}
}
}
extension InternetLoader: WKNavigationDelegate {
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
webView.evaluateJavaScript("document.body.innerHTML") { [weak self] (result, error) in
if let error = error {
print("Error executing JavaScript: \(error.localizedDescription)")
} else if let htmlContent = result as? String {
self?.resultHtml = htmlContent
}
self?.continuation?.resume(returning: self?.resultHtml)
}
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
continuation?.resume(throwing: error)
}
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
continuation?.resume(throwing: error)
}
}
let loader = InternetLoader()
var html = ""
if let confirmedHtml = try? await loader.getHTML(from: URL(string: "https://stackoverflow.com/questions")!) {
html = confirmedHtml
}
print(html)