Сначала смотрите обновления ниже.
Я пытаюсь очистить все модераторы для указанного sub-reddit на reddit. API только позволяет вам получить все имена пользователей модераторов для sub-reddit, поэтому сначала я получил все это, а затем выполнил дополнительный запрос для каждого из этих профилей, чтобы получить URL аватара. Это закончилось тем, что превысило лимит API.
Поэтому вместо этого я хочу просто получить источник следующей страницы и разбить его на страницы, собирая 10 имен пользователей и URL-адреса аватаров на каждой странице. Это приведет к опросу сайта с меньшим количеством запросов. Я понимаю, как выполнять разбиение на страницы, но сейчас я пытаюсь понять, как собрать имена пользователей и примыкающие URL аватара.
Итак, возьмите следующий URL:
https://www.reddit.com/r/videos/about/moderators/
Так что я буду потяните весь исходный код страницы,
Добавьте все имена пользователей и ссылки на моды в объект мода, затем в массив.
Было бы неплохо использовать регулярное выражение в строке, которую я получаю?
Это мой код, любая помощь будет полезна:
func tester() {
let url = URL(string: "https://www.reddit.com/r/videos/about/moderators")!
let task = URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else {
print("\(error)")
return
}
let string = String(data: data, encoding: .utf8)
let regexUsernames = try? NSRegularExpression(pattern: "href=\"/user/[a-z0-9]\"", options: .caseInsensitive)
var results = regexUsernames?.matches(in: string as String, options: [], range: NSRange(location: 0, length: string.length))
let regexProfileURLs = try? NSRegularExpression(pattern: "><img src=\"[a-z0-9]\" style", options: .caseInsensitive)
print("\(results)") // This shows as empty array
}
task.resume()
}
У меня есть также пробовал следующее, но получаю эту ошибку:
Can't form Range with upperBound < lowerBound
Код:
func tester() {
let url = URL(string: "https://www.reddit.com/r/videos/about/moderators")!
let task = URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else {
print("data was nil")
return
}
guard let htmlString = String(data: data, encoding: .utf8) else {
print("cannot cast data into string")
return
}
let leftSideOfValue = "href=\"/user/"
let rightSideOfValue = "\""
guard let leftRange = htmlString.range(of: leftSideOfValue) else {
print("cannot find range left")
return
}
guard let rightRange = htmlString.range(of: rightSideOfValue) else {
print("cannot find range right")
return
}
let rangeOfTheValue = leftRange.upperBound..<rightRange.lowerBound
print(htmlString[rangeOfTheValue])
}
ОБНОВЛЕНИЕ:
Итак, я дошел до того, что он даст мне первое имя пользователя, однако я зацикливаюсь и просто получаю одно и то же снова и снова. Как лучше всего двигаться на каждом шаге? Есть ли способ сделать что-то вроде let newHTMLString = htmlString.dropFirst (k:?), Чтобы заменить htmlString подстрокой, которая находится после элементов, которые мы только что получили?
func tester() {
let url = URL(string: "https://www.reddit.com/r/pics/about/moderators")!
let task = URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else {
print("data was nil")
return
}
guard let htmlString = String(data: data, encoding: .utf8) else {
print("cannot cast data into string")
return
}
let counter = htmlString.components(separatedBy:"href=\"/user/")
let count = counter.count
for i in 0...count {
let leftSideOfUsernameValue = "href=\"/user/"
let rightSideOfUsernameValue = "\""
let leftSideOfAvatarURLValue = "><img src=\""
let rightSideOfAvatarURLValue = "\">"
guard let leftRange = htmlString.range(of: leftSideOfUsernameValue) else {
print("cannot find range left")
return
}
guard let rightRange = htmlString.range(of: rightSideOfUsernameValue) else {
print("cannot find range right")
return
}
let username = htmlString.slice(from: leftSideOfUsernameValue, to: rightSideOfUsernameValue)
print(username)
guard let avatarURL = htmlString.slice(from: leftSideOfAvatarURLValue, to: rightSideOfAvatarURLValue) else {
print("Error")
return
}
print(avatarURL)
}
}
task.resume()
}
Я также пробовал:
let endString = String(avatarURL + rightSideOfAvatarURLValue)
let endIndex = htmlString.index(endString.endIndex, offsetBy: 0)
let substringer = htmlString[endIndex...]
htmlString = String(substringer)