-
-
Notifications
You must be signed in to change notification settings - Fork 427
Expand file tree
/
Copy pathAppleDocumentationSearchService.swift
More file actions
60 lines (51 loc) · 2.1 KB
/
Copy pathAppleDocumentationSearchService.swift
File metadata and controls
60 lines (51 loc) · 2.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import Foundation
import SwiftSoup
import WebKit
import WebScrapper
struct AppleDocumentationSearchService: SearchService {
func search(query: String) async throws -> WebSearchResult {
let queryEncoded = query
.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? ""
let url = URL(string: "https://developer.apple.com/search/?q=\(queryEncoded)")!
let scrapper = await WebScrapper()
let html = try await scrapper.fetch(url: url) { document in
DeveloperDotAppleResultParser.validate(document: document)
}
return try DeveloperDotAppleResultParser.parse(html: html)
}
}
enum DeveloperDotAppleResultParser {
static func validate(document: SwiftSoup.Document) -> Bool {
guard let _ = try? document.select("ul.search-results").first
else { return false }
return true
}
static func parse(html: String) throws -> WebSearchResult {
let document = try SwiftSoup.parse(html)
let searchResult = try? document.select("ul.search-results").first
guard let searchResult else { return .init(webPages: []) }
var results: [WebSearchResult.WebPage] = []
for element in searchResult.children() {
if let titleElement = try? element.select("p.result-title"),
let link = try? titleElement.select("a").attr("href"),
!link.isEmpty
{
let title = (try? titleElement.text()) ?? ""
let snippet = (try? element.select("p.result-description").text())
?? (try? element.select("ul.breadcrumb-list").text())
?? ""
results.append(WebSearchResult.WebPage(
urlString: {
if link.hasPrefix("/") {
return "https://developer.apple.com\(link)"
}
return link
}(),
title: title,
snippet: snippet
))
}
}
return WebSearchResult(webPages: results)
}
}