【问题标题】:Download Image from HTML WKWebView从 HTML WKWebView 下载图像
【发布时间】:2018-02-02 23:41:04
【问题描述】:

以下是我从 WKWebView 中加载的 URL 获取的标签之一

在 DidFinish 上是否可以将该图像作为 UIImage 获取?

【问题讨论】:

    标签: ios swift wkwebview


    【解决方案1】:

    为了实现这一点,我使用了一些库来提供帮助。

    在您的项目中使用 pod(或 carthage 或任何您喜欢的)插入以下库:

    SwiftSoup

    AlamofireImage

    一旦您的项目设置了这些库,我们就可以开始了。

    在您的故事板中,放置 2 个元素,在我的中,我有一个 WKWebView 和一个 ImageView。 只需设置约束以确保测试时一切都在屏幕上。 ?

    那么在代码中我们会有:

    import UIKit
    import WebKit
    import SwiftSoup
    import AlamofireImage
    
    
    class ViewController: UIViewController, WKNavigationDelegate {
        @IBOutlet weak var webView: WKWebView!
        @IBOutlet weak var imageView: UIImageView!
    
        let url = URL(string: "https://www.google.com")
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
            webView.navigationDelegate = self
    
            let urlReq = URLRequest(url: url!, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 1)
            webView!.load(urlReq)
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
            webView.evaluateJavaScript("document.documentElement.outerHTML.toString()",
                                       completionHandler: { (html: Any?, error: Error?) in
                                        do{
                                            let doc: Document = try SwiftSoup.parse(html as! String)
                                            let pngs: Elements = try doc.select("img[src$=.png]")
                                            let srcsStringArray: [String?] = pngs.array().map { try? $0.attr("src").description }
                                            for imgs in srcsStringArray {
                                                if let imgUrl = imgs {
                                                    var finalUrl = URL(string: "")
                                                    if imgUrl.contains("http") {
                                                        finalUrl = URL(string: String(format: imgUrl))
                                                    } else {
                                                        finalUrl = URL(string: String(format: "%@%@", (self.url?.absoluteString)!, imgUrl))
                                                    }
                                                    self.imageView.af_setImage(withURL: finalUrl!)
                                                    print(finalUrl) //debug URL
                                                }
                                            }
                                        } catch Exception.Error(let type, let message){
                                            print(type, message)
                                        } catch {
                                            print("error")
                                        }
            })
        }
    }
    

    此示例按原样运行。

    当然,您需要根据自己的需要对其进行调整,但您有所有的元素可以做到这一点。

    编辑 1:

    我只有一张图片,如果你有多张图片,你必须在行上正确处理:

    for imgs in srcsStringArray {...}

    编辑 2:

    验证码已准备就绪,正在获取准确加载的图像。 在这种情况下,您不需要 AlamofireSwiftSoup

    import UIKit
    import WebKit
    
    class ViewController: UIViewController, WKNavigationDelegate {
        @IBOutlet weak var webView: WKWebView!
        @IBOutlet weak var imageView: UIImageView!
    
        let url = URL(string: "YOUR_URL")
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
            webView.navigationDelegate = self
    
            let urlReq = URLRequest(url: url!, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 1)
            webView!.load(urlReq)
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    
            let str = "var c = document.createElement('canvas'); var ctx = c.getContext('2d'); ctx.drawImage(document.getElementById('captcha_id'), 100, 40); var value = c.toDataURL(); value.split(',')[1]; "
    
            self.webView.evaluateJavaScript(str) { (value, error) in
                 if error == nil {
                     if let img = value as? String {
                          self.imageView.image = self.base64ToImage(base64: img)
                     }
                 }
             }
        }
    
        func base64ToImage(base64: String) -> UIImage? {
            var img: UIImage = UIImage()
            if (!base64.isEmpty) {
                if let decodedData = NSData(base64Encoded: base64 , options: NSData.Base64DecodingOptions.ignoreUnknownCharacters) {
                    if let decodedimage = UIImage(data: decodedData as Data) {
                        img = (decodedimage as UIImage?)!
                        return img
                    }
                }
            }
            return nil
        }
    }
    

    【讨论】:

    • "是否有可能在该 URL 处获得在 WebView 中加载的相同图像?"代码完全符合您的要求。 “问题是我在那个屏幕上有验证码,所以如果我再次点击 URL,那么该图像就会改变”它不应该发生,因为代码需要加载 HTML 代码并且不在页面上做任何其他帖子。但是解决方案回答了你的问题,你没有提到任何关于验证码的事情。必须在您的代码中处理特殊性。如果有帮助,请采纳答案
    • 你能提供你要访问的网站来获取图片吗?我可以尝试在这里做一些测试
    • 看看再回来
    • 非常感谢。你付出了很多努力。它完全解决了我的问题。欣赏你的工作。
    • 用上面代码中的这一行替换:let str = "var c = document.createElement('canvas'); var ctx = c.getContext('2d'); const list = document.getElementsByTagName('img'); ctx.drawImage(list[1], 100, 40); var value = c.toDataURL(); value.split(',')[1]; "
    猜你喜欢
    • 1970-01-01
    • 2020-05-18
    • 2022-11-17
    • 2019-03-25
    • 2017-12-29
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    相关资源
    最近更新 更多