douliandan7340 2018-05-25 14:51
浏览 36
已采纳

从网址转到lang解析JSON

Here is my situation, i requested to a server with a GET and received a JSON format. i'm using go lang, and implemented it in Go Lang in beego web framework.

So i have implemented it like this one,

func (d *Tom) Get() {
    //passengersFile, err := http.Get("https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=MSFT&interval=1min&apikey=KLMH2VFJ0LCFNOX5")
    resp, err := http.Get("https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=MSFT&interval=1min&apikey=KLMH2VF0LCFNOX5")
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    //fmt.Printf("%#v
", resp)

    dec := json.NewDecoder(resp.Body)
    if dec == nil {
        panic("Failed to start decoding JSON data")
    }

    json_map := make(map[string]interface{})

    err = dec.Decode(&json_map)
        for k, v := range json_map {
            if k == "Meta Data"{
                    continue
            }
            fmt.Printf("key[%s] value[%s]
", k, v)
        }
    if err != nil {
        panic(err)
    }

        d.Data["json"] = &json_map
    d.ServeJSON()
}

the format of the incoming json is like that ....

{
  "Meta Data": {
    "1. Information": "Intraday (1min) prices and volumes",
    "2. Symbol": "MSFT",
    "3. Last Refreshed": "2018-05-25 09:31:00",
    "4. Interval": "1min",
    "5. Output Size": "Compact",
    "6. Time Zone": "US/Eastern"
  },
  "Time Series (1min)": {
    "2018-05-24 14:23:00": {
      "1. open": "98.1432",
      "2. high": "98.1661",
      "3. low": "98.1238",
      "4. close": "98.1500",
      "5. volume": "19106"
    },
    "2018-05-24 14:24:00": {
      "1. open": "98.1500",
      "2. high": "98.1700",
      "3. low": "98.1400",
      "4. close": "98.1650",
      "5. volume": "18279"
    },
    "2018-05-24 14:25:00": {
      "1. open": "98.1650",
      "2. high": "98.2000",
      "3. low": "98.1600",
      "4. close": "98.1900",
      "5. volume": "32085"
    }
  }
}

Now i want to get the "Time Series (1min)" values and iterate on them to get each value of the "Date Time" values, like "1. open" ... etc. And of course save them on a single json and return it for those who requested it. Any help will be greatly appreciated!

  • 写回答

1条回答 默认 最新

  • drruhc4944 2018-05-25 15:15
    关注

    The actual JSON object is quite, unusual - and it does not lend itself to a simple way of turning it into a struct.

    For demonstration, I will use JSONGen, a great utility for turning JSON into Go structs.

    For the problem at hand, I would probably use a two step approach.

    First, parse the whole document (assuming msft.json contains an API response):

    $ cat msft.json | JSONGen
    type _ struct {
        MetaData struct {
            Information   string `json:"1. Information"`
            Interval      string `json:"4. Interval"`
            LastRefreshed string `json:"3. Last Refreshed"`
            OutputSize    string `json:"5. Output Size"`
            Symbol        string `json:"2. Symbol"`
            TimeZone      string `json:"6. Time Zone"`
        } `json:"Meta Data"`
        TimeSeries1min struct {
            _ struct {
                Close  string `json:"4. close"`
                High   string `json:"2. high"`
                ...
    

    The problem is the repeated elements, keyed by datetime, which would probably be better modelled as a list. Anyway, with jq we can parse out a relevant piece and generate another struct:

    $ cat msft.json | jq '.["Time Series (1min)"]["2018-05-24 15:47:00"]' | JSONGen
    type _ struct {
        Close  string `json:"4. close"`
        High   string `json:"2. high"`
        Low    string `json:"3. low"`
        Open   string `json:"1. open"`
        Volume string `json:"5. volume"`
    }
    

    Now we can combine the two structs into one. Here is a complete program to parse the JSON input.

    package main
    
    import (
        "encoding/json"
        "fmt"
        "log"
        "os"
    )
    
    type Item struct {
        Close  string `json:"4. close"`
        High   string `json:"2. high"`
        Low    string `json:"3. low"`
        Open   string `json:"1. open"`
        Volume string `json:"5. volume"`
    }
    
    type Response struct {
        MetaData struct {
            Information   string `json:"1. Information"`
            Interval      string `json:"4. Interval"`
            LastRefreshed string `json:"3. Last Refreshed"`
            OutputSize    string `json:"5. Output Size"`
            Symbol        string `json:"2. Symbol"`
            TimeZone      string `json:"6. Time Zone"`
        } `json:"Meta Data"`
        TimeSeries1min map[string]Item `json:"Time Series (1min)"`
    }
    

    We can model the time series as a map of OHLC items. The parsing now gets really simple:

    func main() {
        resp := Response{}
        if err := json.NewDecoder(os.Stdin).Decode(&resp); err != nil {
            log.Fatal(err)
        }
        for k, v := range resp.TimeSeries1min {
            fmt.Printf("%s\t%s\t%s\t%s\t%s\t%s\t%s
    ",
                resp.MetaData.Symbol, resp.MetaData.LastRefreshed, k,
                v.Open, v.High, v.Low, v.Close)
        }
    }
    

    While will output something like:

    $ go run main.go < msft.json
    MSFT    2018-05-25 10:53:00 2018-05-25 10:49:00 98.6292 98.6292 98.5700 98.5750
    MSFT    2018-05-25 10:53:00 2018-05-25 10:40:00 98.8700 98.8701 98.7900 98.8300
    MSFT    2018-05-25 10:53:00 2018-05-25 10:22:00 98.6460 98.6500 98.6000 98.6300
    

    ...

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 echarts动画效果失效的问题。官网下载的例子。
  • ¥60 许可证msc licensing软件报错显示已有相同版本软件,但是下一步显示无法读取日志目录。
  • ¥15 Attention is all you need 的代码运行
  • ¥15 一个服务器已经有一个系统了如果用usb再装一个系统,原来的系统会被覆盖掉吗
  • ¥15 使用esm_msa1_t12_100M_UR50S蛋白质语言模型进行零样本预测时,终端显示出了sequence handled的进度条,但是并不出结果就自动终止回到命令提示行了是怎么回事:
  • ¥15 前置放大电路与功率放大电路相连放大倍数出现问题
  • ¥30 关于<main>标签页面跳转的问题
  • ¥80 部署运行web自动化项目
  • ¥15 腾讯云如何建立同一个项目中物模型之间的联系
  • ¥30 VMware 云桌面水印如何添加