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,这意味着您确实需要一个网络视图。否则手动启动 URLRequest
s 并观察响应就足够了。
我有一组 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,这意味着您确实需要一个网络视图。否则手动启动 URLRequest
s 并观察响应就足够了。