url 数据任务在使用 SwiftSoup 解析时未显示正确的内容? Swift 5
url data task is not showing the right content when parsed with SwiftSoup? Swift 5
我是 swift 的新手,有一个应用程序可以执行简单的 url 数据任务来解析该网站的 html 内容。我试图加载某些元素,但没有得到我在手动检查时在网站上看到的内容。我真的不知道是什么问题。
我想我的问题是;如果我手动搜索该网站,是否有加载内容的方法?
相关代码如下:
import SwiftSoup
let config = URLSessionConfiguration.default
config.httpAdditionalHeaders = ["User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"]
let session = URLSession(configuration: config)
let url = URL(string: link)
let task = session.dataTask(with: url!) { [self] (data, response, error) in
do {
let htmlContent = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
let doc: Document = try SwiftSoup.parse(htmlContent! as String)
let elements = try doc.getAllElements().array()
} catch Exception.Error(type: let type, Message: let message) {
print(type)
print(message)
} catch {
print("error")
}
}
请告诉我是否有任何方法可以做到这一点,即使它涉及使用不同的包来解析数据。这对我的应用程序非常重要。如果能提供任何帮助,我将不胜感激!
谢谢。
我怀疑问题可能是您的用户代理被发送到您正在解析其响应的网站。
用户代理是一个字符串,随请求一起发送到 url(作为附加 header)。它可以识别您的身份,以便发送适当的回复。
例如,如果您在 Big Sur 上 Mac 从 Safari 请求用户代理可能是:
"Mozilla/5.0 (Macintosh; Intel Mac OS X 11_5_2) AppleWebKit/605.1.15 (KHTML, like壁虎) Version/14.1.2 Safari/605.1.15"
而从 iPad 开始可能是:
"Mozilla/5.0 (iPad; CPU OS 14_7_1 喜欢 Mac OS X) AppleWebKit/605.1.15(KHTML,如 Gecko)Version/14.1.2 Mobile/15E148 Safari/604.1"
为请求提供服务的站点使用用户代理来确定对 return 的响应类型以及要包含的功能(完整站点、移动站点、文本站点等)。
对于 Swift 应用程序中的 URLSession,用户代理是应用程序的包名称。因此,该网站可能会对此感到困惑,并且 return 显示的内容与您在浏览器中访问它时看到的内容不同。
部分选项:
探索该站点,它可能有更好的 url 用于获取您想要的信息。
更改您要发送的 user-agent 字符串。基本步骤是:
let config = URLSessionConfiguration.default
config.httpAdditionalHeaders = ["User-Agent": "User-Agent String Here"]
let session = URLSession(configuration: config)
您可能需要调整您对共享 session 的使用以支持此功能(例如:使用您的配置创建一个 session 并使用它,如上所述,或者检查是否有使用共享 session).
为您的请求覆盖 header 的方法
我找到了适合我的解决方案。相关代码如下:
private let webView: WKWebView = {
let prefs = WKPreferences()
prefs.javaScriptEnabled = true
let config = WKWebViewConfiguration()
config.preferences = prefs
let webView = WKWebView(frame: .zero, configuration: config)
return webView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(webView)
webView.navigationDelegate = self
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
parseData()
}
func parseData() {
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) { [unowned self] in
webView.evaluateJavaScript("document.body.innerHTML") { result, error in
guard let htmlContent = result, error == nil else {
print("error")
return
}
do {
let doc = try SwiftSoup.parse(htmlContent as! String)
var allProducts = try doc.getAllElements.array()
} catch {
print("error")
}
}
}
}
首先使用 WebView 加载网站,然后在延迟后解析数据对我来说是一个可行的解决方案。固定延迟可能不是最好的主意,所以如果有任何其他建议,将不胜感激!
我是 swift 的新手,有一个应用程序可以执行简单的 url 数据任务来解析该网站的 html 内容。我试图加载某些元素,但没有得到我在手动检查时在网站上看到的内容。我真的不知道是什么问题。
我想我的问题是;如果我手动搜索该网站,是否有加载内容的方法?
相关代码如下:
import SwiftSoup
let config = URLSessionConfiguration.default
config.httpAdditionalHeaders = ["User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"]
let session = URLSession(configuration: config)
let url = URL(string: link)
let task = session.dataTask(with: url!) { [self] (data, response, error) in
do {
let htmlContent = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
let doc: Document = try SwiftSoup.parse(htmlContent! as String)
let elements = try doc.getAllElements().array()
} catch Exception.Error(type: let type, Message: let message) {
print(type)
print(message)
} catch {
print("error")
}
}
请告诉我是否有任何方法可以做到这一点,即使它涉及使用不同的包来解析数据。这对我的应用程序非常重要。如果能提供任何帮助,我将不胜感激!
谢谢。
我怀疑问题可能是您的用户代理被发送到您正在解析其响应的网站。
用户代理是一个字符串,随请求一起发送到 url(作为附加 header)。它可以识别您的身份,以便发送适当的回复。
例如,如果您在 Big Sur 上 Mac 从 Safari 请求用户代理可能是:
"Mozilla/5.0 (Macintosh; Intel Mac OS X 11_5_2) AppleWebKit/605.1.15 (KHTML, like壁虎) Version/14.1.2 Safari/605.1.15"
而从 iPad 开始可能是:
"Mozilla/5.0 (iPad; CPU OS 14_7_1 喜欢 Mac OS X) AppleWebKit/605.1.15(KHTML,如 Gecko)Version/14.1.2 Mobile/15E148 Safari/604.1"
为请求提供服务的站点使用用户代理来确定对 return 的响应类型以及要包含的功能(完整站点、移动站点、文本站点等)。
对于 Swift 应用程序中的 URLSession,用户代理是应用程序的包名称。因此,该网站可能会对此感到困惑,并且 return 显示的内容与您在浏览器中访问它时看到的内容不同。
部分选项:
探索该站点,它可能有更好的 url 用于获取您想要的信息。
更改您要发送的 user-agent 字符串。基本步骤是:
let config = URLSessionConfiguration.default
config.httpAdditionalHeaders = ["User-Agent": "User-Agent String Here"]
let session = URLSession(configuration: config)
您可能需要调整您对共享 session 的使用以支持此功能(例如:使用您的配置创建一个 session 并使用它,如上所述,或者检查是否有使用共享 session).
为您的请求覆盖 header 的方法我找到了适合我的解决方案。相关代码如下:
private let webView: WKWebView = {
let prefs = WKPreferences()
prefs.javaScriptEnabled = true
let config = WKWebViewConfiguration()
config.preferences = prefs
let webView = WKWebView(frame: .zero, configuration: config)
return webView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(webView)
webView.navigationDelegate = self
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
parseData()
}
func parseData() {
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) { [unowned self] in
webView.evaluateJavaScript("document.body.innerHTML") { result, error in
guard let htmlContent = result, error == nil else {
print("error")
return
}
do {
let doc = try SwiftSoup.parse(htmlContent as! String)
var allProducts = try doc.getAllElements.array()
} catch {
print("error")
}
}
}
}
首先使用 WebView 加载网站,然后在延迟后解析数据对我来说是一个可行的解决方案。固定延迟可能不是最好的主意,所以如果有任何其他建议,将不胜感激!