在Swift中从WKWebview获取HTML

65

我使用WKWebView登录网站,现在我想解析该网站的HTML。我如何在Swift中访问网站的HTML?我知道在UIWebView中如何操作,但不知道在WKWebView中如何操作。

谢谢您的帮助!

4个回答

124
如果你等到页面加载完成,你就可以使用:
webView.evaluateJavaScript("document.documentElement.outerHTML.toString()") {
    print(html)
}

你还可以注入一些返回HTML的javascript代码。
let script = WKUserScript(source: javascriptString, injectionTime: injectionTime, forMainFrameOnly: true)
userContentController.addUserScript(script)
self.webView.configuration.userContentController.addScriptMessageHandler(self, name: "didGetHTML")



func userContentController(userContentController: WKUserContentController,
        didReceiveScriptMessage message: WKScriptMessage) {
     
    guard message.name == "didGetHTML", 
        let html = message.body as? String else { 
        return 
    }

    print(html)
}

你可以注入的JavaScript代码大致如下:
webkit.messageHandlers.didGetHTML.postMessage(document.documentElement.outerHTML.toString());

在 internal-<style> 中修改了 cssRule 后,Webview 显示的是我修改后的样式。但是 document.documentElement.outerHTML.toString() 没有获取到新的 cssRule。你有什么解决方案吗? - Kyle KIM
@Onato 如何加载抓取的HTML? - onCompletion
我的理解是这个问题是如何获取网页的HTML,以便重新加载它并使其完全相同的功能。这个被接受的答案并没有回答这个问题。至少在我的应用程序中,测试结果显示尽管页面正常显示,但没有可点击的链接。我目前没有头绪如何保存HTML并重新加载它,使页面保持原样。也许可以使用String(contentsOf: url)方法获取HTML,并尝试这种方式,而不是通过wkWebView本身加载? - drew..
1
我建议您发布一个新问题,包括更多关于您想要实现的目标的细节。随意在此处链接它。 - Onato
1
哎呀..尽管有完整的网页,但我却打印出了(<html><head></head><body></body></html>)。 - ScottyBlades

12

Swift <-> WKWebView

从WKWebView获取HTML内容

wkWebView.evaluateJavaScript("document.body.innerHTML", completionHandler: { (value: Any!, error: Error!) -> Void in
    if error != nil {
        //Error logic
        return
    }

    //let result = value as? String
    //Main logic
})

将HTML设置到WKWebView中
//Do not forget to extend a class from `WKNavigationDelegate`

func someFunction() {
    let wkWebView = WKWebView()
    
    wkWebView.loadHTMLString("<html><body></body></html>", baseURL: nil)
    wkWebView.navigationDelegate = self as? WKNavigationDelegate
}

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    //ready to be processed
}

[Swift <-> UIWebView]


2

我在这里试图获取DROPBOX新API的令牌并获得结果的线索。(我正在实现他们的流程,但不使用他们的SDK)

现在Dropbox使用网页作为登录页面,并回调YOUR url以便您可以处理令牌。

import WebKit
import SwiftUI

// some code from:
// https://benoitpasquier.com/create-webview-in-swiftui/
// THX pasquier!

let APP_KEY = "YOUR APP KEY"
let REDIRECT_URI = "<YOUR SITE>.dropbox_auth.php"
let DB_URL = "https://www.dropbox.com/1/oauth2/authorize?client_id=APP_KEY&token_access_type=offline&response_type=code&redirect_uri=REDIRECT_URI"

class MyWKDelegate: NSObject, WKNavigationDelegate{
    
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        print("End loading")
        webView.evaluateJavaScript("document.body.innerHTML", completionHandler: { result, error in
            
            if let html = result as? String {
                    print(html)
                }
            })
    }
}

struct WebView: UIViewRepresentable {
        
    typealias UIViewType = WKWebView

    let webView: WKWebView
    
    func makeUIView(context: Context) -> WKWebView {
        return webView
    }
    
    func updateUIView(_ uiView: WKWebView, context: Context) { }
}


class WebViewModel: ObservableObject {
    let webView: WKWebView
    let url: URL!
    let delegate = MyWKDelegate()
    
    init() {
        webView = WKWebView(frame: .zero)
        webView.navigationDelegate = delegate

        let urlStr = DB_URL.replacingOccurrences(of: "APP_KEY", with: APP_KEY).replacingOccurrences(of: "REDIRECT_URI", with: REDIRECT_URI)
        print(urlStr)
        url = URL(string: urlStr)

        loadUrl()
    }
    
    func loadUrl() {
        webView.load(URLRequest(url: url))
    }
}

0

将答案1和3结合起来对我很有帮助:

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
   print("End loading")        
   webView.evaluateJavaScript("document.documentElement.outerHTML", completionHandler: { result, error in         
      if let datHtml = result as? String {
         print(datHtml)
         // parse datHtml here
         }
      } )
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接