Golang:如何parse/unmarshal/decode一个json数组API响应?
Golang :How to parse/unmarshal/decode a json array API response?
我正在尝试将位于 https://wikimedia.org/api/rest_v1/metrics/pageviews/per-article/en.wikipedia.org/all-access/all-agents/Smithsonian_Institution/daily/20160101/20170101
的维基百科 API 的响应解析为一个结构数组,我将继续打印出查看计数
但是,为了实现这个 returns 我在终端中什么都没有尝试实现的代码 运行 它?
我失败的代码如下。
type Post struct {
Project string `json:"project"`
Article string `json:"article"`
Granularity string `json:"granularity"`
Timestamp string `json:"timestamp"`
Access string `json:"access"`
Agent string `json:"agent"`
Views int `json:"views"`
}
func main(){
//The name of the wikipedia post
postName := "Smithsonian_Institution"
//The frequency of
period := "daily"
//When to start the selection
startDate := "20160101"
//When to end the selection
endDate := "20170101"
url := fmt.Sprintf("https://wikimedia.org/api/rest_v1/metrics/pageviews/per-article/en.wikipedia.org/all-access/all-agents/%s/%s/%s/%s", postName, period, startDate, endDate)
//Get from URL
req, err := http.Get(url)
if err != nil{
return
}
defer req.Body.Close()
var posts []Post
body, err := ioutil.ReadAll(req.Body)
if err != nil {
panic(err.Error())
}
json.Unmarshal(body, &posts)
// Loop over structs and display the respective views.
for p := range posts {
fmt.Printf("Views = %v", posts[p].Views)
fmt.Println()
}
}
接收来自 API 的 json 响应的最佳方法是什么,例如上面提到的那个,然后将该数组解析为结构数组,然后可以将其插入到数据存储或相应地打印出来。
谢谢
结构声明可以相互嵌套。
以下结构应该可以从 json 转换而来:
type resp struct {
Items []struct {
Project string `json:"project"`
Article string `json:"article"`
Granularity string `json:"granularity"`
Timestamp string `json:"timestamp"`
Access string `json:"access"`
Agent string `json:"agent"`
Views int `json:"views"`
} `json:"items"`
}
我用 json-to-go 生成了它,这在使用 JSON API 时非常节省时间。
您的解决方案:
data := struct {
Items []struct {
Project string `json:"project"`
Article string `json:"article"`
Granularity string `json:"granularity"`
Timestamp string `json:"timestamp"`
Access string `json:"access"`
Agent string `json:"agent"`
Views int `json:"views"`
} `json:"items"`
}{}
// you don't need to convert body to []byte, ReadAll returns []byte
err := json.Unmarshal(body, &data)
if err != nil { // don't forget handle errors
}
我正在尝试将位于 https://wikimedia.org/api/rest_v1/metrics/pageviews/per-article/en.wikipedia.org/all-access/all-agents/Smithsonian_Institution/daily/20160101/20170101
的维基百科 API 的响应解析为一个结构数组,我将继续打印出查看计数
但是,为了实现这个 returns 我在终端中什么都没有尝试实现的代码 运行 它?
我失败的代码如下。
type Post struct {
Project string `json:"project"`
Article string `json:"article"`
Granularity string `json:"granularity"`
Timestamp string `json:"timestamp"`
Access string `json:"access"`
Agent string `json:"agent"`
Views int `json:"views"`
}
func main(){
//The name of the wikipedia post
postName := "Smithsonian_Institution"
//The frequency of
period := "daily"
//When to start the selection
startDate := "20160101"
//When to end the selection
endDate := "20170101"
url := fmt.Sprintf("https://wikimedia.org/api/rest_v1/metrics/pageviews/per-article/en.wikipedia.org/all-access/all-agents/%s/%s/%s/%s", postName, period, startDate, endDate)
//Get from URL
req, err := http.Get(url)
if err != nil{
return
}
defer req.Body.Close()
var posts []Post
body, err := ioutil.ReadAll(req.Body)
if err != nil {
panic(err.Error())
}
json.Unmarshal(body, &posts)
// Loop over structs and display the respective views.
for p := range posts {
fmt.Printf("Views = %v", posts[p].Views)
fmt.Println()
}
}
接收来自 API 的 json 响应的最佳方法是什么,例如上面提到的那个,然后将该数组解析为结构数组,然后可以将其插入到数据存储或相应地打印出来。
谢谢
结构声明可以相互嵌套。
以下结构应该可以从 json 转换而来:
type resp struct {
Items []struct {
Project string `json:"project"`
Article string `json:"article"`
Granularity string `json:"granularity"`
Timestamp string `json:"timestamp"`
Access string `json:"access"`
Agent string `json:"agent"`
Views int `json:"views"`
} `json:"items"`
}
我用 json-to-go 生成了它,这在使用 JSON API 时非常节省时间。
您的解决方案:
data := struct {
Items []struct {
Project string `json:"project"`
Article string `json:"article"`
Granularity string `json:"granularity"`
Timestamp string `json:"timestamp"`
Access string `json:"access"`
Agent string `json:"agent"`
Views int `json:"views"`
} `json:"items"`
}{}
// you don't need to convert body to []byte, ReadAll returns []byte
err := json.Unmarshal(body, &data)
if err != nil { // don't forget handle errors
}