htmlswiftswiftsoup

How to parse the specific content in the HTML to my App


I'm trying to parse data from a website to my own application. I manage to get the html and print the html using AlamoFire but I don't know how am I going to get the specific data from that html file.

Here I get the HTML and I'm trying to get the exchange data

func scrapeExchangeRate() -> Void {
    Alamofire.request("https://yatirim.akbank.com/tr-tr/doviz/sayfalar/default.aspx").responseString {
        response in
        print("\(response.result.isSuccess)")
        if let html = response.result.value {
            self.parseHTML(html: html)
        }
    }
}

func parseHTML(html: String) -> Void {
    print("\(html)")
}

The statement prints out the entire HTML file as expected but I'm trying to extract the data here from the var starts like this

var dovizHesaplama = '{"EUR":{"USD":{"ask":1.14065,"bid":1.14058,"time":"2019-01-16T22:21:45.3497922+03:00"},"GBP":{"ask":0.88690615037710907,"bid":0.88705864053507533,"time":"2019-01-16T22:06:44+03:00"},"XAU":{"ask":0.00088175725295877431,"bid":0.00088189402550006575,"time":"2019-01-16T22:06:44+03:00"},"AUD":{"ask":1.5884277955716475,"bid":1.5889941487879631,"time":"2019-01-16T22:06:44+03:00"},"CAD":{"ask":1.51113312,"bid":1.510812268,"time":"2019-01-16T22:06:44+03:00"},"CHF":{"ask":1.128901305,"bid":1.12860391,"time":"2019-01-16T22:06:44+03:00"},"CNY":{"ask":7.7056610749999992,"bid":7.70233674,"time":"2019-01-16T22:06:44+03:00"},"DKK":{"ask":7.4654401849999994,"bid":7.463613346,"time":"2019-01-16T22:06:44+03:00"},"ETH":{"ask":0.0091456863373957659,"bid":0.0091480590311196659,"time":"2019-01-16T22:06:44+03:00"},"NOK":{"ask":9.74137913,"bid":9.738043924,"time":"2019-01-16T22:06:44+03:00"},"NZD":{"ask":1.680975905,"bid":1.68064463,"time":"2019-01-16T22:06:44+03:00"},"RUB":{"ask":75.636729629999991,"bid":75.603231241999993,"time":"2019-01-16T22:06:44+03:00"},"SAR":{"ask":4.2788062799999995,"bid":4.277859348,"time":"2019-01-16T22:06:44+03:00"},"SEK":{"ask":10.261743659999999,"bid":10.25894681,"time":"2019-01-16T22:06:44+03:00"},"TRL":{"ask":6.09837116,"bid":6.094803288,"time":"2019-01-16T22:06:44+03:00"}

and I'm interested in the USD exchange rates starting here:

I specifically want to extract data like some specific currencies exchange rate bid and ask prices vs the USD. How do I select those specific values?

"USD":{"ask":1.0101010101010102,"bid":1.0105092966855296,"time":"2019-01-16T21:05:25.7963428+03:00"},"GBP":{"ask":0.78619318968011376,"bid":0.78663342416746818,"time":"2019-01-16T20:50:16+03:00"},"XAU":{"ask":0.00078045880988148267,"bid":0.00078094926132039845,"time":"2019-01-16T20:50:16+03:00"},"AUD":{"ask":1.4070218834113528,"bid":1.4087680143392298,"time":"2019-01-16T20:50:16+03:00"},"CAD":{"ask":1.3381818181818181,"bid":1.338419563459984,"time":"2019-01-16T20:50:16+03:00"},"CNY":{"ask":6.8226262626262635,"bid":6.82407033144705,"time":"2019-01-16T20:50:16+03:00"},"DKK":{"ask":6.6151515151515161,"bid":6.6170169765561839,"time":"2019-01-16T20:50:16+03:00"},"ETH":{"ask":0.0080872779031305863,"bid":0.00809184254232487,"time":"2019-01-16T20:50:16+03:00"},"NOK":{"ask":8.6312121212121227,"bid":8.6322756669361365,"time":"2019-01-16T20:50:16+03:00"},"NZD":{"ask":1.4894949494949494,"bid":1.4896928051738076,"time":"2019-01-16T20:50:16+03:00"},"RUB":{"ask":67.052121212121222,"bid":67.059013742926439,"time":"2019-01-16T20:50:16+03:00"},"SAR":{"ask":3.7890909090909091,"bid":3.790016168148747,"time":"2019-01-16T20:50:16+03:00"},"SEK":{"ask":9.0835353535353534,"bid":9.0852869846402591,"time":"2019-01-16T20:50:16+03:00"},"TRL":{"ask":5.4033333333333342,"bid":5.4027890056588523,"time":"2019-01-16T20:50:16+03:00"},"XAG":{"ask":0.064750064750064756,"bid":0.0649010466721599,"time":"2019-01-16T20:50:16+03:00"},"XPD":{"ask":0.000743858997658927,"bid":0.0007465456764177438,"time":"2019-01-16T20:50:16+03:00"},"XPT":{"ask":0.0012522016836102078,"bid":0.001253951426656652,"time":"2019-01-16T20:50:16+03:00"}}

Solution

  • Like gavsta707 commented you can look up the var in the HTML content using the regular expression var dovizHesaplama = '(.+)'.

    Then decode the JSON using the JSONDecoder. Note that you will need to specify the date format which is YYYY-MM-dd'T'HH:mm:ss.SSSSSSSZZZZZ.

    Some code that does this might look like

    import Foundation
    
    struct ExchangeRates: Codable {
    
        struct Rate: Codable {
            let ask: Double
            let bid: Double
            let time: Date
        }
    
        struct OtherRates: Codable {
            let EUR: Rate
            let GBP: Rate
            let XAU: Rate
            let AUD: Rate
            let CAD: Rate
            let CHF: Rate
            let CNY: Rate
            let DKK: Rate
            let ETH: Rate
            let NOK: Rate
            let NZD: Rate
            let RUB: Rate
            let SAR: Rate
            let SEK: Rate
            let TRL: Rate
            let XAG: Rate
            let XPD: Rate
            let XPT: Rate
        }
    
        let USD: OtherRates
    }
    
    let jsonPattern = try NSRegularExpression(pattern: "var dovizHesaplama = '(.+)'")
    let decoder = JSONDecoder()
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "YYYY-MM-dd'T'HH:mm:ss.SSSSSSSZZZZZ"
    decoder.dateDecodingStrategy = .formatted(dateFormatter)
    
    let data = try Data(contentsOf: URL(string: "https://yatirim.akbank.com/tr-tr/doviz/sayfalar/default.aspx")!)
    if let string = String(data: data, encoding: .utf8) as NSString? {
        if let match = jsonPattern.firstMatch(in: string as String, range: NSRange(location: 0, length: string.length)) {
            let json = string.substring(with: match.range(at: 1))
            let rates = try decoder.decode(ExchangeRates.self, from: json.data(using: .utf8)!)
            print(rates)
        }
    }