在Go中使用gotoken循环访问谷歌地方API

时间:2017-02-02 04:38:13

标签: api go google-api

我无法在Go中循环使用Google Places API。

Google的Places API最多返回20个结果,并带有一个pagetoken参数,以添加到查询中以返回接下来的20个结果,直到没有任何结果。

我目前能够发送查询请求,返回json并在终端输出它,但是当我尝试循环回来并将pagetoken参数添加到查询时,它会运行但只返回第一个页面结果再次但使用另一个页面标记。任何想法我做错了什么?

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "strconv"
    // "os"
)

type GooglePlaces struct {
    HTMLAttributions []interface{} `json:"html_attributions"`
    NextPageToken    string        `json:"next_page_token"`
    Results          []struct {
        Geometry struct {
            Location struct {
                Lat float64 `json:"lat"`
                Lng float64 `json:"lng"`
            } `json:"location"`
            Viewport struct {
                Northeast struct {
                    Lat float64 `json:"lat"`
                    Lng float64 `json:"lng"`
                } `json:"northeast"`
                Southwest struct {
                    Lat float64 `json:"lat"`
                    Lng float64 `json:"lng"`
                } `json:"southwest"`
            } `json:"viewport"`
        } `json:"geometry"`
        Icon         string `json:"icon"`
        ID           string `json:"id"`
        Name         string `json:"name"`
        OpeningHours struct {
            OpenNow     bool          `json:"open_now"`
            WeekdayText []interface{} `json:"weekday_text"`
        } `json:"opening_hours,omitempty"`
        Photos []struct {
            Height           int      `json:"height"`
            HTMLAttributions []string `json:"html_attributions"`
            PhotoReference   string   `json:"photo_reference"`
            Width            int      `json:"width"`
        } `json:"photos,omitempty"`
        PlaceID   string   `json:"place_id"`
        Reference string   `json:"reference"`
        Scope     string   `json:"scope"`
        Types     []string `json:"types"`
        Vicinity  string   `json:"vicinity"`
        Rating    float64  `json:"rating,omitempty"`
    } `json:"results"`
    Status string `json:"status"`
}


func searchPlaces(page string) {
    apiKey := "API_KEY_HERE"
    keyword := "residential+bank+33131"
    latLong := "25.766144,-80.190589"
    pageToken := page
    var buffer bytes.Buffer

    buffer.WriteString("https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=")
    buffer.WriteString(latLong)
    buffer.WriteString("&radius=50000&keyword=")
    buffer.WriteString(keyword)
    buffer.WriteString("&key=")
    buffer.WriteString(apiKey)
    buffer.WriteString("&pagetoken=")
    buffer.WriteString(pageToken)

    query := buffer.String()

    // PRINT CURRENT SEARCH
    println("query is ", query)
    println("\n")


    // SEND REQUEST WITH QUERY
    resp, err := http.Get(query)
    if err != nil {
        log.Fatal(err)
    }
    // CLOSE THE PRECLOSER THATS RETURNED WITH HTTP RESPONSE
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatal(err)
    }

    res := GooglePlaces{}
    json.Unmarshal([]byte(body), &res)

    var listings bytes.Buffer
    for i := 0; i < len(res.Results); i++ {
        listings.WriteString(strconv.Itoa(i + 1))
        listings.WriteString("\nName: ")
        listings.WriteString(res.Results[i].Name)
        listings.WriteString("\nAddress: ")
        listings.WriteString(res.Results[i].Vicinity)
        listings.WriteString("\nPlace ID: ")
        listings.WriteString(res.Results[i].PlaceID)
        listings.WriteString("\n---------------------------------------------\n\n")
    }
    listings.WriteString("\npagetoken is now:\n")
    listings.WriteString(res.NextPageToken)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(listings.String())
    fmt.Printf("\n\n\n")

    // LOOP BACK THROUGH FUNCTION
    searchPlaces(res.NextPageToken)

}

func main() {
    searchPlaces("")
}

1 个答案:

答案 0 :(得分:1)

请注意,documentation for Google Place Search表示:

  

发出next_page_token和有效时间之间会有短暂的延迟。

但是在您的代码中,您会立即使用新令牌发送请求。

在使用令牌之前添加睡眠几秒钟可以解决我的问题。我将您的代码更改为

    if res.NextPageToken != "" {
        time.Sleep(3000 * time.Millisecond)
        searchPlaces(res.NextPageToken)
    } else {
        fmt.Println("No more pagetoken, we're done.")
    }

遗憾的是,没有关于令牌有效期多长的文档。