快速加载网站以在不加载视图的情况下抓取代码 |网络套件
Posted
技术标签:
【中文标题】快速加载网站以在不加载视图的情况下抓取代码 |网络套件【英文标题】:Swift Load Website to Scrape Code Without Loading View | WebKit 【发布时间】:2020-04-10 03:48:43 【问题描述】:我有一组 Google 新闻文章网址。 Google 新闻文章网址立即重定向到真实网址,即:CNBC.com/.... 我正在尝试提取真实的重定向网址。我以为我可以遍历列表并在 WebView 中加载 Google 新闻链接,然后在 1 秒后在 DispatchQueue 中调用 webView.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
【问题讨论】:
从别人的网站上抓取内容是不是有点黏糊糊的? 最后我查了一下,这就是 Google 新闻的字面意思……一个大众聚合器/刮板。 聚合与抓取不同。 Google 新闻很可能是由 RSS 提要驱动的,当您点击标题时,您会转到创建该内容的网站。但是,当您抓取 Google 的页面时,您正在利用 Google 创建的内容并将其用作您自己的内容。谷歌拥有一百万种不同事物的 API,所以也许有一个用于他们汇总的新闻——如果是这样,使用它,你就不需要抓取任何东西。如果没有,那么也许您应该考虑选择自己的资源集。 【参考方案1】:您的尝试有两个问题:
1) 您在循环中使用的是同一个 Web 视图,并且由于在 Web 视图完成加载之前循环内没有任何内容会阻塞,因此您最终会在每次循环通过时取消上一个请求。
2) 即使您确实在循环内阻塞,在一秒钟后访问 URL 也不会可靠地工作,因为导航很容易花费比这更长的时间。
我建议做的是继续使用单个 Web 视图(以节省资源),但使用其导航委托界面一个一个解析 URL。
这是一个粗略的例子,可以给你一个基本的想法:
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()
这会输出以下已解析的 URL:
[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,这意味着您确实需要 Web 视图。否则手动启动URLRequest
s 并观察响应就足够了。
【讨论】:
以上是关于快速加载网站以在不加载视图的情况下抓取代码 |网络套件的主要内容,如果未能解决你的问题,请参考以下文章
如何在不加载视图的情况下重新加载/刷新部分视图中的级联下拉列表
在不重新加载整个表格视图的情况下更改 UITableView 的部分页眉/页脚标题
在不加载 .mat 文件的情况下检查变量是不是在 .mat 文件中的快速方法? 'who'/'whos' 并不比加载快.. 比 'who' 更好的选择?