iosswiftweb-scrapingswiftsoup

how to filter a string in swift and get the middle result


I am trying to do web scraping since the author of the website does not provide an API but he wanted me to do an App for the website. The website is about getting a time table for the day. So the print values that I get are these.

1: module Kevin Street 1: modulesTime line-height: 13px; font-size: 11px; top: 0px; height: 200px; display: block; width: 25%; left: 0%; right: 0px;

I want to get the value between the the 'top: ' and 'px;' so that means I am looking for the value of 0 which is in the middle of the string. And same for the height I am trying to save the value of 200 in a variable.

Here is a the code that I have that get the module for the title and the moduleTime which is the style of the element.

import Foundation
import SwiftSoup

enum HTMLError: Error {
    case badInnerHTML
}

struct CalendarResponse {

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

        let doc = try SwiftSoup.parse(htmlString)
        let modulesTimeAM = try doc.getElementsByClass("wc-cal-event ui-corner-all calSeriesNaN").array()
        let modulesTimePM = try doc.getElementsByClass("wc-cal-event ui-corner-all calBaseSeries").array()
        let modules = try doc.getElementsByClass("wc-time ui-corner-top").array()

        for index in 1...modules.count {
            let module = try modules[index - 1].text()
            print("\(index): module \n", module)
            let moduleTime = index <= modulesTimeAM.count ? try modulesTimeAM[index - 1].attr("style") : try modulesTimePM[index - 1 - modulesTimeAM.count].attr("style")
            print("\(index): modulesTime \n", moduleTime)
        }
    }

}

Solution

  • You can slice from string to string

    extension String {
    
        func slice(from: String, to: String) -> String? {
            return (range(of: from)?.upperBound).flatMap { substringFrom in
                (range(of: to, range: substringFrom..<endIndex)?.lowerBound).map { substringTo in
                    String(self[substringFrom..<substringTo])
                }
            }
        }
    }
    

    and use it with

    let top = htmlString.slice(from: "top: ", to: "px") // 0 
    let height = htmlString.slice(from: "height: ", to: "px") // 200
    

    Maybe it is not htmlString in your case. You will get it :)