這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
訪問一個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 mainimport ( "encoding/json" "fmt" "github.com/bitly/go-simplejson" "io/ioutil" "net/http" //"reflect" "regexp" "strconv" "strings")//const blkSize int = 10000type 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)}