Swift 加载网站以在不加载视图的情况下抓取代码 |网络套件

Swift Load Website to Scrape Code Without Loading View | WebKit

我有一组 Google 篇新闻文章 url。 Google 新闻文章 urls 立即重定向到真实的 urls,即:CNBC.com/.... 我正在尝试拉出真实的,重定向的 url.我想我可以循环遍历列表并在 WebView 中加载 Google News link,然后在 1 秒后在 DispatchQueue 中调用 webView.url 以获得真正的 url,但是这不起作用。

如何快速获取重定向的 url 列表?

这是您可以用来重现问题的我的代码:

        let webView = WKWebView()
        let myList = [URL(string: "https://news.google.com/articles/CAIiEDthIxbgofssGWTpXgeJXzwqGQgEKhAIACoHCAow2Nb3CjDivdcCMJ_d7gU?hl=en-US&gl=US&ceid=US%3Aen"), URL(string: "https://news.google.com/articles/CAIiEP5m1nAOPt-LIA4IWMOdB3MqGQgEKhAIACoHCAowocv1CjCSptoCMPrTpgU?hl=en-US&gl=US&ceid=US%3Aen")]

        for url in myList {
            guard let link = url else {continue}
            self.webView.loadUrl(string: link.absoluteString)

            DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
                let redirectedLink = self.webView.url
                print("HERE redirected url: ", redirectedLink) // this does not work
            }
        }

您的尝试有两个问题:

1) 您在循环中使用了同一个 Web 视图,并且由于在 Web 视图完成加载之前循环内没有任何内容阻塞,因此您最终会在每次循环通过时取消上一个请求。

2) 即使您确实在循环内进行了阻塞,一秒钟后访问 URL 也不会可靠地工作,因为导航很容易花费比这更长的时间。

我建议做的是继续使用单个 Web 视图(以节省资源),但使用其导航委托界面逐个解析 URLs .

这是一个粗略的例子,可以给你一个基本的概念:

import UIKit
import WebKit

@objc class RedirectResolver: NSObject, WKNavigationDelegate {

    private var urls: [URL]
    private var resolvedURLs = [URL]()
    private let completion: ([URL]) -> Void
    private let webView = WKWebView()

    init(urls: [URL], completion: @escaping ([URL]) -> Void) {
        self.urls = urls
        self.completion = completion
        super.init()
        webView.navigationDelegate = self
    }

    func start() {
        resolveNext()
    }

    private func resolveNext() {
        guard let url = urls.popLast() else {
            completion(resolvedURLs)
            return
        }
        let request = URLRequest(url: url)
        webView.load(request)
    }

    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        resolvedURLs.append(webView.url!)
        resolveNext()
    }

}


class ViewController: UIViewController {

    private var resolver: RedirectResolver!

    override func viewDidLoad() {
        super.viewDidLoad()

        resolver = RedirectResolver(
            urls: [URL(string: "https://news.google.com/articles/CAIiEDthIxbgofssGWTpXgeJXzwqGQgEKhAIACoHCAow2Nb3CjDivdcCMJ_d7gU?hl=en-US&gl=US&ceid=US%3Aen")!, URL(string: "https://news.google.com/articles/CAIiEP5m1nAOPt-LIA4IWMOdB3MqGQgEKhAIACoHCAowocv1CjCSptoCMPrTpgU?hl=en-US&gl=US&ceid=US%3Aen")!],
            completion: { urls in
                print(urls)
            })
        resolver.start()
    }

}

这将输出以下已解决的 URLs:

[https://amp.cnn.com/cnn/2020/04/09/politics/trump-coronavirus-tests/index.html, https://www.cnbc.com/amp/2020/04/10/asia-markets-coronavirus-china-inflation-data-currencies-in-focus.html]

另一件需要注意的事情是,那些 URL 的重定向似乎特别依赖于 JavaScript,这意味着您确实需要一个网络视图。否则手动启动 URLRequests 并观察响应就足够了。