访问一个api, 返回如下数据:
{"status":"success","data":{"resultType":"matrix","result":[{"metric":{},"values":[[1473820558.361,"28765"],[1473820573.361,"28768"],[1473820588.361,"28772"],[1473820603.361,"28776"],[1473820618.361,"28780"],[1473820633.361,"28783"],[1473820648.361,"28786"],[1473820663.361,"28790"],[1473820678.361,"28793"],[1473820693.361,"28796"],[1473820708.361,"28799"],[1473820723.361,"28802"],[1473820738.361,"28806"],[1473820753.361,"28809"],[1473820768.361,"28817"],[1473820783.361,"28829"],[1473820798.361,"28832"],[1473820813.361,"28858"],[1473820828.361,"28862"],[1473820843.361,"28867"],[1473820858.361,"28873"]]}]}}
js, err := simplejson.NewJson(body)
if err != nil {
panic(err.Error())
}
//解析数组
arr, _ := js.Get("data").Get("result").GetIndex(0).Get("values").Array()
length := len(arr)
for i := 0; i < length; i++ {
x:= *js.Get("data").Get("result").GetIndex(0).Get("values").GetIndex(i).GetIndex(0))
//fmt.Println(*js.Get("data").Get("result").GetIndex(0).Get("values").GetIndex(i).GetIndex(1))
}
访问一个api, 返回如下数据:
{
"data": {
"trend": {
"fields": [
"min_time",
"last_px",
"avg_px",
"business_amount"
],
"600570.SS": [
[
201501090930,
54.98,
54.98,
28327
],
[
201501090931,
54.63,
54.829486,
49700
]
]
}
}
}
需要解析 600570.SS 后的json数据,用了 simplejson包
js, err := simplejson.NewJson([]byte(str))
check(err)
arr, _ := js.Get("data").Get("trend").Get("600570.ss").Array()
可是对返回的arr数据,用了18般武艺都解析不了。 arr类型理论是一个interface{}类型,但是里面又包含了四组数据,对于这类json数据,网上文档都没有解析的方法。 反复尝试后,用reflect.type 测试了下,发现系统把arr 认定为[]interface 类型,于是类型断言后,遍历。 这回可以把里面数据分拆开了,系统又把里面的数据判断为 json.Number数据类型。 然后就没有然后了.... 经过这一番摸索,对于空接口、类型断言,json包内部的一些设定有了更深的理解:空接口就是因为它灵活,所以在使用时要经过一系列的判断。
上代码:
package main
import (
"encoding/json"
"fmt"
"github.com/bitly/go-simplejson"
"io/ioutil"
"net/http"
//"reflect"
"regexp"
"strconv"
"strings"
)
//const blkSize int = 10000
type trend struct {
date int64
last_px float32 //最新价
avg_px float32 //平均价
volumn float32 //成交量
}
var (
lines []string
blksLen []int
isGB bool
)
func check(err error) {
if err != nil {
panic(err.Error())
}
}
func Get(url string) ([]byte, error) {
defer func() {
if err := recover(); err != nil {
fmt.Println(err)
}
}()
resp, err := http.Get(url)
check(err)
//Println(resp.StatusCode)
if resp.StatusCode != 200 {
panic("FUCK")
}
return ioutil.ReadAll(resp.Body)
}
func strip(src string) string {
src = strings.ToLower(src)
re, _ := regexp.Compile(`<!doctype.*?>`)
src = re.ReplaceAllString(src, "")
re, _ = regexp.Compile(`<!--.*?-->`)
src = re.ReplaceAllString(src, "")
re, _ = regexp.Compile(`<script[\S\s]+?</script>`)
src = re.ReplaceAllString(src, "")
re, _ = regexp.Compile(`<style[\S\s]+?</style>`)
src = re.ReplaceAllString(src, "")
re, _ = regexp.Compile(`<.*?>`)
src = re.ReplaceAllString(src, "")
re, _ = regexp.Compile(`&.{1,5};|&#.{1,5};`)
src = re.ReplaceAllString(src, "")
src = strings.Replace(src, "\r\n", "\n", -1)
src = strings.Replace(src, "\r", "\n", -1)
return src
}
func Do(url string) string {
body, err := Get(url)
check(err)
plainText := strip(string(body))
return plainText
}
func main() {
str := Do("http://xxx:8081/quote/v1/trend?prod_code=600570.SS&fields=last_px,business_amount,avg_px")
js, err := simplejson.NewJson([]byte(str))
check(err)
arr, _ := js.Get("data").Get("trend").Get("600570.ss").Array()
t := len(arr)
stockdata := trend{}
trends := make([]trend, 0, t)
for _, v := range arr {
//就在这里i进行类型判断
value, _ := v.([]interface{})
for k, u := range value {
x, _ := u.(json.Number) //类型断言
y, _ := strconv.ParseFloat(string(x), 64) //将字符型号转化为float64
//v := reflect.ValueOf(k)
//fmt.Println("type:", v.Type())
switch k {
case 0:
stockdata.date = int64(y)
case 1:
stockdata.last_px = float32(y)
case 2:
stockdata.volumn = float32(y)
case 3:
stockdata.avg_px = float32(y)
default:
fmt.Println("结构体中不存在此元素")
}
}
trends = append(trends, stockdata)
}
fmt.Println(trends)
}