【问题标题】:Get request returns data in Thunder client/Postman but gives blank data in Golang codeGet 请求在 Thunder 客户端/Postman 中返回数据,但在 Golang 代码中给出空白数据
【发布时间】:2023-01-30 23:00:50
【问题描述】:

我正在尝试使用 Golang net/http 从 API 获取数据。当我从 VS Code 甚至 Postman 使用 Thunder 客户端时,我得到了正确的数据,但是当我试图从 Golang 代码中获取数据时,我得到一个空的响应。

数据分两步获取:

  1. 使用初始 GET 请求获取 cookie(这部分在两者中都工作正常)
  2. 使用 cookie 进行另一个 GET 请求以获取所需的数据。 (这是在 Golang 中给出空白响应的步骤,在下面给出的 Postman 链接中被命名为历史数据)

    这是 Golang 代码。代码可能有点长,但这只是因为多行添加标题。

    var BaseURL string = "https://www.nseindia.com"
    
    func ReqConfig() *http.Request {
        req, _ := http.NewRequest("GET", BaseURL, nil)
        req.Header.Add("Accept", "*/*")
        req.Header.Add("Accept-Encoding", "gzip, deflate, br")
        req.Header.Add("Accept-Language", "en-GB,en-US;q=0.9,en;q=0.8")
        req.Header.Add("Connection", "keep-alive")
        req.Header.Add("Host", "www.nseindia.com")
        req.Header.Add("Referer", "https://www.nseindia.com/get-quotes/equity")
        req.Header.Add("X-Requested-With", "XMLHttpRequest")
        req.Header.Add("sec-fetch-dest", "empty")
        req.Header.Add("sec-fetch-mode", "cors")
        req.Header.Add("pragma", "no-cache")
        req.Header.Add("sec-fetch-site", "same-origin")
        req.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36")
        fmt.Println(1, req.Header.Get("Cookie"))
    
        res, err := http.DefaultClient.Do(req)
        if err != nil {
            panic(err)
        }
        defer res.Body.Close()
        for _, cookie := range res.Cookies() {
            req.AddCookie(cookie)
        }
    
        // TODO: Remove the need to call this API twice. This is just a temporary fix.
        res, err = http.DefaultClient.Do(req)
        if err != nil {
            panic(err)
        }
        defer res.Body.Close()
        for _, cookie := range res.Cookies() {
            req.AddCookie(cookie)
        }
    
    
        cookies := req.Cookies()
        for i := 0; i < len(cookies); i++ {
            for j := i + 1; j < len(cookies); j++ {
                if cookies[i].Name == cookies[j].Name {
                    cookies = append(cookies[:j], cookies[j+1:]...)
                    j--
                }
            }
        }
        req.Header.Del("Cookie")
        for _, cookie := range cookies {
            req.AddCookie(cookie)
        }
        fmt.Println("Fetched cookies")
    
        return req
    }
    
    
    func HistoricalEQ(symbol string, from string, to string, series string) {
        req := ReqConfig()
    
        query := req.URL.Query()
        query.Add("symbol", symbol)
        query.Add("from", from)
        query.Add("to", to)
        query.Add("series", "[\""+series+"\"]")
        req.URL.RawQuery = query.Encode()
        req.URL.Path = "/api/historical/cm/equity"
    
        client := &http.Client{Timeout: 40 * time.Second}
        res, err := client.Do(req)
        if err != nil {
            panic(err)
        }
        defer res.Body.Close()
    
        var data map[string]interface{}
        json.NewDecoder(res.Body).Decode(&data)
    
            // Prints `map[]` and not the whole json data which is provided in Postman req
        fmt.Println(data)
    }
    
    
    func main() {
        symbol := "PAYTM"
        series := "EQ"
        from_date := time.Date(2023, 1, 1, 0, 0, 0, 0, time.Local).Format("02-01-2006")
        to_date := time.Date(2023, 1, 24, 0, 0, 0, 0, time.Local).Format("02-01-2006")
        HistoricalEQ(symbol, from_date, to_date, series)
    }
    
    

    如果您能够从其他方式获取数据仅限 Go 语言来自 GET https://www.nseindia.com/api/historical/cm/equity?symbol=PAYTM&amp;series=[%22EQ%22]&amp;from=28-12-2022&amp;to=28-01-2023,那也可以解决我的问题。您可以通过https://www.nseindia.com/get-quotes/equity?symbol=PAYTM 查看网站前端。我要问的 GET 请求可以通过转到历史数据选项卡并单击过滤器按钮来触发

    python中的类似代码:https://github.com/jugaad-py/jugaad-data/blob/47bbf1aa39ebec3a260579c76ff427ea06e42acd/jugaad_data/nse/history.py#L61

【问题讨论】:

    标签: go http


    【解决方案1】:

    1️⃣解码错误处理遗漏

    err := json.NewDecoder(res.Body).Decode(&data)
    if err != nil {
        log.Fatalf("decode request: %v", err)
    }
    
    invalid character '' looking for beginning of value
    

    2️⃣ 看起来响应数据已经被压缩了(gzip数据以魔术序列 0x1f 0x8b 开头)。如果您检查回复的Headers,您会看到

    ...
    Content-Encoding:[gzip] ??????
    Content-Length:[1890] 
    Content-Type:[application/json; charset=utf-8] 
    ...
    

    它看起来像真的

    3️⃣ 尝试手动处理压缩

        client := &http.Client{Timeout: 40 * time.Second}
        res, err := client.Do(req)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Println(res.Header)
    
        var reader io.ReadCloser
        switch res.Header.Get("Content-Encoding") {
        case "gzip":
            reader, err = gzip.NewReader(res.Body)
        default:
            reader = res.Body
        }
        defer reader.Close()
    
        var data map[string]interface{}
        err = json.NewDecoder(reader).Decode(&data)
        if err != nil {
            log.Fatalf("decode request: %v", err)
        }
    
        fmt.Println(data) ?? // map[data:[map[CH_52WEEK_HIGH_PRICE:994 CH_52WEEK_LOW_PRICE:438.35 CH_CLOSING_PRICE:543.55 CH_ISIN:INE982J01020 CH_LAST_TRADED_PRICE:542.2 CH_MARKET_TYPE:N ...
    

    【讨论】:

      猜你喜欢
      • 2021-07-20
      • 2021-10-15
      • 1970-01-01
      • 2020-02-23
      • 2019-11-04
      • 2020-08-02
      • 1970-01-01
      • 1970-01-01
      • 2017-10-21
      相关资源
      最近更新 更多