在 Swift 中从 WKWebview 获取 HTML

Posted

技术标签:

【中文标题】在 Swift 中从 WKWebview 获取 HTML【英文标题】:Get HTML from WKWebview in Swift 【发布时间】:2016-04-17 13:14:54 【问题描述】:

我使用 WKWebView 登录网站,现在我想解析网站的 html。如何快速访问网站 html?我知道它对 UIWebView 是如何工作的,但对 WKWebView 却不是。

感谢您的帮助!

【问题讨论】:

【参考方案1】:

在询问令牌形式 DROPBOX 新 APIS 后,我在这里尝试获取有关获得结果的线索。 (我在没有他们 SDK 的所有东西的情况下实现他们的流程) 希望能帮助到别人。

现在 Dropbox 使用网页作为登录名,并回调您的 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))
    

【讨论】:

【参考方案2】:

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

[get/set HTML from UIWebView]

【讨论】:

【参考方案3】:

如果您等到页面加载完毕,您可以使用:

webView.evaluateJavaScript("document.documentElement.outerHTML.toString()", 
                           completionHandler:  (html: Any?, error: Error?) in
    print(html)
)

您还可以注入一些 javascript 来返回 HTML。

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) 

        if message.name == "didGetHTML" 
            if let html = message.body as? String 
                print(html)
            
        

您可以注入的 javascript 类似于:

webkit.messageHandlers.didGetHTML.postMessage(document.documentElement.outerHTML.toString());

【讨论】:

在 internal- @Onato 如何加载抓取的 html? 我对这个问题的解释是:如何从网页中获取 HTML,以便我可以重新加载它并使其功能完全相同。这个接受的答案不回答这个问题。至少在我的应用程序中,尽管页面正确显示,但测试显示没有可点击的链接。我目前不知道如何保存 HTML 并重新加载它以使页面保持原样。也许使用 String(contentsOf: url) 来获取 HTML 并尝试这种方式,而不是通过 wkWebView 本身加载? 我建议发布一个新问题,包括您尝试实现的目标的更多详细信息。随意在此处链接。 嗯.. 即使有一个完整的网页,我也会打印:()。跨度>

以上是关于在 Swift 中从 WKWebview 获取 HTML的主要内容,如果未能解决你的问题,请参考以下文章

如何在swift 4中从WKWebView中的网页中删除DIV标签?

使用 evaluateJavascript 从 WKWebView 获取 HTML,然后将其存储在变量中(使用 Swift)

登录 ios swift 后从 wkwebview 获取令牌

当特定屏幕以 html 显示时,从 WKWebView 向 Swift 获取通知

Swift 4 WKWebView cookie 获取和删除同步问题

如何在 Swift 中从 Facebook 获取用户名