javascriptswiftswiftsoup

Swift, Reach multiple classes with SwiftSoup for parsing HTML file


I am parsing a HTML site. (using swiftsoup cocoapods) I reached the data with classes by getElementByClass method.

struct OddResponse {

let odds: [Odd]

init(_ innerHTML: Any?) throws {
guard let htmlString = innerHTML as? String else { throw
    HTMLError.badInnerHTML }

let doc = try SwiftSoup.parse(htmlString)
let leagues = try doc.getElementsByClass("league").array()
let times = try doc.getElementsByClass("time").array()
let hometeams = try doc.getElementsByClass("homeTeam").array()
let awayteams = try doc.getElementsByClass("awayTeam").array()
let dropprimaries = try doc.getElementsByClass("drop primary").array()

let odd1highdrops = try doc.getElementsByClass("odds-dropping drop-high").array()
let odd2highdrops = try doc.getElementsByClass("odds-dropping drop-high").array()

    var odds = [Odd]()
    for i in 0..<times.count {
        let league = try leagues[i].text()
        let time = try times[i].text()

        let odd1highdrop = try odd1highdrops[i].text()
        let odd2highdrop = try odd2highdrops[i].text()

        print(odd1highdrop)
        print(odd2highdrop)

        let odd = Odd(league: league, time: time, odd1highdrop: odd1highdrop, odd2highdrop: odd2highdrop)
        odds.append(odd)
    }
    self.odds = odds
}

But in my case, the HTML is changing. So the "odds-dropping drop-high" class name can be update on every minute. How can I reach the child classes or parent with swift. Does anybody know?


Solution

  • Extracted from the question:

    This works perfect for me.

    struct OddResponse {
    
    let odds: [Odd]
    
    init(_ innerHTML: Any?) throws {
        guard let htmlString = innerHTML as? String else { throw
            HTMLError.badInnerHTML }
    
    
        var odds = [Odd]()
        let doc = try SwiftSoup.parse(htmlString)
        if let body = try doc.getElementsByClass("tablesorter tablesorter-default hasStickyHeaders").last()?.getElementsByTag("tbody").first() {
            for tr in body.children() {
    
                let league = try tr.getElementsByClass("league").first()!.text()
                let time = try tr.getElementsByClass("time").first()!.text()
    
                var otherOdd1dropping = ""
                var odd1dropping = ""
                var oddDroppingType = 0
    
                if let node = try tr.getElementsByClass("odds odds-1 odds-dropping").first() {
                    odd1dropping = try node.text()
                }else if let node = try tr.getElementsByClass("odds odds-1 odds-dropping drop-medium").first() {
                    otherOdd1dropping = try node.text()
                    oddDroppingType = 1
                }else{
                    otherOdd1dropping = try tr.getElementsByClass("odds odds-1 odds-dropping drop-high").first()!.text()
                    oddDroppingType = 2
                }
    
                let odd = Odd(league: league, time: time, odd1dropping: odd1dropping, otherOdd1dropping: otherOdd1dropping, oddDroppingType: oddDroppingType)
                odds.append(odd)
            }
        }
        self.odds = odds
    }