Google 使用 Alamofire 搜索失败(iOS、Swift、JSON、HTML)

Google Search with Alamofire Fails (iOS, Swift, JSON, HTML)

请帮忙!几个月来,我一直在尝试在我的 Swift 应用程序上执行一个简单的 Google 搜索,但我的头已经撞破了墙!

我已经尝试使用 ALAMOFIRE 和常规 URLRequest,但由于结果似乎只有 HTML 格式,我似乎无法正确解析结果。即使您查看 HTML 格式,该代码也是针对网页的,并且不包括搜索结果。

我希望将搜索结果放入简单词典中。 这是我的代码:

        let googleUrl:String = "https://cse.google.com/cse/publicurl?&output=json&cx=<MyGoogleKey>:<MyGoogleSKey>&q=q=+normal+search"

        // Trying with AlamoFire:

        Alamofire.request(googleUrl).response { response in
            print("Request: \(response.request)")
            print("Response: \(response.response)")
            print("Error: \(response.error)")
        }.responseJSON(completionHandler: { response in
             print("ResponseJSON: \(response)")
        }).responseData(completionHandler: { response in
              print("ResponseData: \(response)")
        }).responseString(completionHandler: { response in
              print("ResponseString: \(response)")
        })

如您所见,我在几乎所有 Alamofire 支持的类型中都尝试了响应,但一无所获。

这是错误 #1 (.responseJSON):

无法读取数据,因为它的格式不正确。 ResponseJSON: FAILURE: responseSerializationFailed(Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=字符 0 周围的无效值。}))

这是数据响应 (.responseData): 响应数据:成功:4337 字节

这是响应 HTML (.responseString)

响应字符串:成功:

*> Google 自定义搜索

(function(){var cookie_path='/cse/';var path_copy='/coop/';window._gaq = window._ga...._AND_SO_ON_TILL_FULL_HTML_PAGE_IN_A_STRING....*

* 我只希望我能在一个简单的字典中得到搜索结果...

有人吗?请?

您似乎在使用自定义搜索 API 嵌入网页。

这个documentation是你想做的。

下面是一个使用堆栈溢出作为搜索域的示例。

import UIKit
import Alamofire

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        search(query: "swift") { (results) in

            for result in results {

                dump(result)
            }
        }
    }

    func search(query:String, completion: @escaping (Array<SearchResult>)->()){

        let id = "Custom search engine ID"

        let key = "API key"

        let url = "https://www.googleapis.com/customsearch/v1?key=\(key)&cx=\(id)&q=\(query)"

        Alamofire.request(url).responseJSON { (response) in

            var results = Array<SearchResult>()

            if let dict = response.value as? Dictionary<String,Any> {

                if let items = dict["items"] as? Array<Dictionary<String,Any>> {

                    for item in items {

                        if let result = SearchResult(dict: item) {

                            results.append(result)

                        } else {

                            print("Incomplete search result data.")
                        }
                    }
                }
            }

            completion(results)
        }
    }
}

我有这个结构来更好地存储搜索结果。它不包含 JSON 结果所包含的所有值。我只是选择了这些进行测试。

struct SearchResult {

    var displayLink: String

    var formattedUrl: String

    var htmlFormattedUrl: String

    var htmlSnippet: String

    var htmlTitle: String

    var link: String

    var snippet: String

    var title: String

    init?(dict:Dictionary<String,Any>) {

        guard

            let displayLink = dict["displayLink"] as? String,

            let formattedUrl = dict["formattedUrl"] as? String,

            let htmlFormattedUrl = dict["htmlFormattedUrl"] as? String,

            let htmlSnippet = dict["htmlSnippet"] as? String,

            let htmlTitle = dict["htmlTitle"] as? String,

            let link = dict["link"] as? String,

            let snippet = dict["snippet"] as? String,

            let title = dict["title"] as? String

        else {

            return nil
        }

        self.displayLink = displayLink

        self.formattedUrl = formattedUrl

        self.htmlFormattedUrl = htmlFormattedUrl

        self.htmlSnippet = htmlSnippet

        self.htmlTitle = htmlTitle

        self.link = link

        self.snippet = snippet

        self.title = title
    }
}

这是 dump(result) 打印出来的几个结果。

▿ CustomGoogleSearch.SearchResult
  - displayLink: "whosebug.com"
  - formattedUrl: "https://whosebug.com/questions/tagged/swift"
  - htmlFormattedUrl: "https://whosebug.com/questions/tagged/<b>swift</b>"
  - htmlSnippet: "<b>Swift</b> is an open-source programming language developed by Apple. Use the tag <br>\nonly for questions about language features, or requiring code in <b>Swift</b>. Use the&nbsp;..."
  - htmlTitle: "Newest &#39;<b>swift</b>&#39; Questions - Stack Overflow"
  - link: "https://whosebug.com/questions/tagged/swift"
  - snippet: "Swift is an open-source programming language developed by Apple. Use the tag \nonly for questions about language features, or requiring code in Swift. Use the ..."
  - title: "Newest \'swift\' Questions - Stack Overflow"

▿ CustomGoogleSearch.SearchResult
  - displayLink: "whosebug.com"
  - formattedUrl: "whosebug.com/documentation/swift/topics"
  - htmlFormattedUrl: "whosebug.com/documentation/<b>swift</b>/topics"
  - htmlSnippet: "58 example-focused documentation topics for <b>Swift</b> Language."
  - htmlTitle: "All <b>Swift</b> Language Topics - Stack Overflow"
  - link: "http://whosebug.com/documentation/swift/topics"
  - snippet: "58 example-focused documentation topics for Swift Language."
  - title: "All Swift Language Topics - Stack Overflow"

获取钥匙

在此 page 上,单击 Get A Key 按钮。

然后您需要select或创建一个Google项目,然后您将生成一个API密钥。所以把这个复制到这里 let key = "API key"

对于搜索引擎 ID,请转到您的 console。现在 select 一个搜索引擎或创建一个新的搜索引擎。您将进入这样的页面。

单击 Search engine ID 按钮,这将显示一个包含您的 ID 的屏幕,然后将其放在这里 let id = "Custom search engine ID"