Извлечение строки JSON из HTML только с помощью iOS API - PullRequest
0 голосов
/ 02 сентября 2018

Я хочу извлечь строку JSON из HTML-документа "без" с помощью стороннего Framework. Я пытаюсь создать iOS Framework, и я не хочу использовать сторонние Framework в нем.

Пример URL: http://www.nicovideo.jp/watch/sm33786214

В этом html есть строка:

Мне нужно извлечь: JSON_String_I_want_to извлечь и преобразовать его в объект JSON.

С сторонним фреймворком "Kanna" это выглядит так:



    if let doc = Kanna.HTML(html: html, encoding: String.Encoding.utf8) {
        if let descNode = doc.css("#js-initial-watch-data[data-api-data]").first {
            let dataApiData = descNode["data-api-data"]
                if let data = dataApiData?.data(using: .utf8) {
                    if let json = try? JSON(data: data, options: JSONSerialization.ReadingOptions.mutableContainers) {

Я искал в Интернете похожий вопрос, но не смог применить его к своему делу: (Я должен признать, что я не совсем следую регулярному выражению)



      if let html = String(data:data, encoding:.utf8) {
        let pattern = "data-api-data=\"(.*?)\".*?>"
        let regex = try! NSRegularExpression(pattern: pattern, options: .caseInsensitive)
        let matches = regex.matches(in: html, options: [], range: NSMakeRange(0, html.count))
        var results: [String] = []
        matches.forEach { (match) -> () in
            results.append( (html as NSString).substring(with: match.rangeAt(1)) )
        }
        if let stringJSON = results.first {
          let d = stringJSON.data(using: String.Encoding.utf8)
          if let json = try? JSONSerialization.jsonObject(with: d!, options: []) as? Any {
            // it does not get here...      
          }

Кто-нибудь разбирается в html и конвертирует его в JSON?

Спасибо.

1 Ответ

0 голосов
/ 02 сентября 2018

Ваш pattern не выглядит плохим, просто значения атрибутов элементов HTML могут использовать символьные объекты.

Вам нужно заменить их на настоящие символы перед тем, как анализировать строку как JSON.

if let html = String(data:data, encoding: .utf8) {
    let pattern = "data-api-data=\"([^\"]*)\""
    let regex = try! NSRegularExpression(pattern: pattern, options: .caseInsensitive)
    let matches = regex.matches(in: html, range: NSRange(0..<html.utf16.count)) //<-USE html.utf16.count, NOT html.count
    var results: [String] = []
    matches.forEach {match in
        let propValue = html[Range(match.range(at: 1), in: html)!]
            //### You need to replace character entities into actual characters
            .replacingOccurrences(of: "&quot;", with: "\"")
            .replacingOccurrences(of: "&apos;", with: "'")
            .replacingOccurrences(of: "&gt;", with: ">")
            .replacingOccurrences(of: "&lt;", with: "<")
            .replacingOccurrences(of: "&amp;", with: "&")
        results.append(propValue)
    }
    if let stringJSON = results.first {
        let dataJSON = stringJSON.data(using: .utf8)!
        do {
            let json = try JSONSerialization.jsonObject(with: dataJSON)
            print(json)
        } catch {
            print(error) //You should not ignore errors silently...
        }
    } else {
        print("NO result")
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...