这里的初学者-我正在尝试找出要谷歌搜索的教程,以帮助我做到这一点:我需要从json脚本的网页中获取一些文本并将其打印到textview中。
当我查看网页的查看源-http://www.sikhnet.com/hukam时-这是我看到的一大段javascript代码,其中需要标记的内容用橙色突出显示:
我读过一些文章说,从Swift4开始,json解析现在是通过Codable原生于Swift的。我还阅读了有关JSONSerialization的信息。但是我不知道哪个更适合实现我的最终目标-将文本从该标签打印到textview?我应该在这里使用哪一个?
我在此网页上也有一个
标记,我想将其打印为textviewcontroller的标题。 Codable / JSONSerialization还可以帮助我做到这一点吗?
答案 0 :(得分:1)
您正在进入网络抓取工具的领域,这些人以作者未曾想到的方式从网页中提取信息。
您的问题是shabad_lines
是JSON对象的属性,该对象是嵌入HTML文档中的一行Javascript代码内。看看您必须跳多少圈才能获得它? Codable
在这里没有帮助。如果您认为“让我们使用regex做到这一点”,那么您自己会遇到另一个问题!
让我们分析一下Javascript代码:
jQuery.extend(Drupal.settings, { ... })
这意味着页面正在向Drupal.setings
对象添加属性。从那个物体取回来怎么样?在Safari或Chrome中打开调试控制台,然后输入以下内容:
Drupal.settings.hukam.shabad_lines.gurmukhi
我们将获得全部8行shabad!加上WKWebView
允许您从网页执行Javascript的事实,并且您的想法应该浮现在脑海。
从概念上讲很简单:加载页面,运行一行Javascript,然后将结果发送回Swift。如果您不熟悉WKWebView
以及事物之间的关系,那么它看起来像是一个谜。嵌套是这样的:
WKWebView
有一个WKWebViewConfiguration
,有一个WKUserContentController
,有一个WKUserScript
。WKWebView
加载网页WkUserScript
执行Javascript并将消息发送回Swift WKUserContentController
定义消息处理程序,即Javascript与Swift进行通信的通道。将所有内容放在一起:
class ViewController: UIViewController {
private var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
// Create a request to load the page
let request = URLRequest(url: URL(string: "http://www.sikhnet.com/hukam")!)
// Create the webview and load the URL
webView = createWebView()
webView.load(request)
}
func createWebView() -> WKWebView {
// This is the Javascript to execute you receive back `shabad_lines`
// property of `Drupal.settings`.
//
// Note the `window.webkit.messageHandlers.shabad.postMessage(...)` call:
// this is how you send a message from Javascript back to Swift. `shabad`
// is a custom message handler that we will define below. Later, when we
// get the message back, we will check that it did come from the `shabad`
// handler and treat it accordingly. You can have as many message handlers
// as you want but you should name them differently so you know where
// each message came from.
let jsSource = "window.webkit.messageHandlers.shabad.postMessage(Drupal.settings.hukam.shabad_lines.gurmukhi)"
// Inject the script, to be executed after the page finishes loading
let script = WKUserScript(source: jsSource, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
//
let contentController = WKUserContentController()
// Define the `shabad` message handler
contentController.add(self, name: "shabad")
// Add the script to the `WKWebView`. The script will executed every time
// you load a webpage, even if it's not sikhnet.com
contentController.addUserScript(script)
// Finally, we can build a web view with the everything we want
let config = WKWebViewConfiguration()
config.userContentController = contentController
return WKWebView(frame: .zero, configuration: config)
}
}
extension ViewController: WKScriptMessageHandler {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
// We received a message from Javascript! Check its name and process the
// message's body
if message.name == "shabad", let lines = message.body as? [String] {
// Now you have your 8 lines of shabad
print(lines)
}
}
}