问题描述
以下代码失败:
let url = URL(string: "https://www.cardboardconnection.com/1987-topps-baseball-cards")!
var request = URLRequest(url: url)
request.setValue("text/html; charset=utf-8",forHTTPHeaderField: "Content-Type")
request.setValue("text/html; charset=utf-8",forHTTPHeaderField: "Accept")
let task = URLSession.shared.dataTask(with: request) {(data,response,error) in
guard let data = data else { return }
print(String(data: data,encoding: .utf8)!)
}
task.resume()
我无法弄清楚这个网站的具体原因是什么导致它在 UTF8 转换时失败。我该如何解决这个问题?什么是正确的转换?只是想从页面中获取原始 HTML。
解决方法
使用 how to detect invalid utf8 unicode/binary in a text file 中的技巧
curl -s https://www.cardboardconnection.com/1987-topps-baseball-cards | grep -axv '.*'
这将显示具有无效 UTF-8 的两行。这里的技巧是 .
只匹配合法解码的字符。
以下有效,但感觉我缺少更简单的方法。
var codeUnits: [UTF32.CodeUnit] = []
let sink = { codeUnits.append($0) }
if transcode(data.makeIterator(),from: UTF8.self,to: UTF32.self,stoppingOnError: false,into: sink) {
let string = String(codeUnits.compactMap { UnicodeScalar($0) }.map(String.init).joined())
print(string)
}
另见 https://stackoverflow.com/a/44611946/97337,其中 Martin R 以更好的方式解决了这个问题(尽管它仍然不简单)。