Golang – 解析来自Twitch TV RESTful服务的JSON字符串数组

huangapple go评论81阅读模式
英文:

Golang - Parsing JSON string arrays from Twitch TV RESTful service

问题

我一直在使用Go语言内置的HTTP库通过HTTP GET请求检索到的JSON对象进行解析。起初,我尝试使用Go中的默认JSON库来完成这个任务,但是我遇到了一些困难(我还是一个Go的新手)。最终,我决定使用另一个库,并且在那之后几乎没有遇到问题,代码如下所示:

package main

import (
	"github.com/antonholmquist/jason"
	"fmt"
	"net/http"
)

func main() {
	resp, err := http.Get("http://tmi.twitch.tv/group/user/deernadia/chatters")
	if nil != err {
		panic(err)
	}
	defer resp.Body.Close()
	body, err := jason.NewObjectFromReader(resp.Body)

	chatters, err := body.GetObject("chatters")
	if nil != err {
		panic(err)
	}

	moderators, err := chatters.GetStringArray("moderators")
	if nil != err {
		panic(err)
	}

	for _, moderator := range moderators {
		fmt.Println(moderator)
	}
}

其中github.com/antonholmquist/jason是我使用的自定义JSON库。

当在Linux shell中运行此代码时,会产生类似以下输出(RESTful服务每30秒左右更新一次,这意味着JSON对象中的值可能会发生变化):

antwan250
bbrock89
boxception22
cmnights
deernadia
fartfalcon
fijibot
foggythought
fulc_
h_ov
iceydefeat
kingbobtheking
lospollogne
nightbot
nosleeptv
octaviuskhan
pateyy
phosphyg
poisonyvie
shevek18
trox94
trox_bot
uggasmesh
urbanelf
walmartslayer
wift3

原始的JSON看起来类似于以下内容(为了简洁起见,删除了一些用户):

{
  "_links": {},
  "chatter_count": 469,
  "chatters": {
    "moderators": [
      "antwan250",
      "bbrock89",
      "boxception22",
      "cmnights",
      "deernadia",
      "fartfalcon",
      "fijibot",
      "foggythought",
      "fulc_",
      "h_ov",
      "iceydefeat",
      "kingbobtheking",
      "lospollogne",
      "nightbot",
      "nosleeptv",
      "octaviuskhan",
      "pateyy",
      "phosphyg",
      "poisonyvie",
      "shevek18",
      "trox94",
      "trox_bot",
      "uggasmesh",
      "urbanelf",
      "walmartslayer",
      "wift3"
    ],
    "staff": [
      "tnose"
    ],
    "admins": [],
    "global_mods": [],
    "viewers": [
      "03xuxu30",
      "0dominic0",
      "3389942",
      "812mfk",
      "910dan",
      "aaradabooti",
      "admiralackbar99",
      "adrian97lol",
      "aequitaso_o",
      "aethiris",
      "afropigeon",
      "ahhhmong",
      "aizaix",
      "aka_magosh",
      "akitoalexander",
      "alex5761",
      "allenhei",
      "allou_fun_park",
      "amilton_tkm",
      "...更多用户,我删除了...",
      "zachn17",
      "zero_x1",
      "zigslip",
      "ziirbryad",
      "zonato83",
      "zorr03body",
      "zourtv"
    ]
  }
}

正如我之前所说,为了达到我所需的目的,我正在使用托管在Github上的自定义库。但是出于学习的目的,我想知道如何使用Go的内置JSON库来完成同样的任务。

明确一下,我想做的是从HTTP GET请求返回的JSON对象中提取每个嵌套的JSON数组中的用户。我还希望以同样的方式获取观众、管理员、全局版主等的列表,但是我认为如果我能看到使用默认的Go库的moderator示例,那么为其他用户类型复制该代码将很容易。

提前谢谢!

英文:

I've been working on parsing a JSON object that I retrieve through an HTTP GET request using Go's built in HTTP library. I initially tried using the default JSON library in Go in order to do this, but I was having a difficult time (I am a novice in Go still). I eventually resorted to using a different library and had little trouble after that, as shown below:

package main

import (
	"github.com/antonholmquist/jason"
	"fmt"
	"net/http"
)

func main() {
	resp, err := http.Get("http://tmi.twitch.tv/group/user/deernadia/chatters")
	if nil != err {
		panic(err)
	}
	defer resp.Body.Close()
	body, err := jason.NewObjectFromReader(resp.Body)

	chatters, err := body.GetObject("chatters")
	if nil != err {
		panic(err)
	}

	moderators, err := chatters.GetStringArray("moderators")
	if nil != err {
		panic(err)
	}

	for _, moderator := range moderators {
		fmt.Println(moderator)
	}
}

Where github.com/antonholmquist/jason corresponds to the custom JSON library I used.

This code produces something similar to the following output when run in a Linux shell (the RESTful service will update about every 30 seconds or so, which means the values in the JSON object will potentially change):

antwan250
bbrock89
boxception22
cmnights
deernadia
fartfalcon
fijibot
foggythought
fulc_
h_ov
iceydefeat
kingbobtheking
lospollogne
nightbot
nosleeptv
octaviuskhan
pateyy
phosphyg
poisonyvie
shevek18
trox94
trox_bot
uggasmesh
urbanelf
walmartslayer
wift3

And the raw JSON looks similar to this (with some of the users removed for brevity):

{
  "_links": {},
  "chatter_count": 469,
  "chatters": {
    "moderators": [
      "antwan250",
      "bbrock89",
      "boxception22",
      "cmnights",
      "deernadia",
      "fartfalcon",
      "fijibot",
      "foggythought",
      "fulc_",
      "h_ov",
      "iceydefeat",
      "kingbobtheking",
      "lospollogne",
      "nightbot",
      "nosleeptv",
      "octaviuskhan",
      "pateyy",
      "phosphyg",
      "poisonyvie",
      "shevek18",
      "trox94",
      "trox_bot",
      "uggasmesh",
      "urbanelf",
      "walmartslayer",
      "wift3"
    ],
    "staff": [
      "tnose"
    ],
    "admins": [],
    "global_mods": [],
    "viewers": [
      "03xuxu30",
      "0dominic0",
      "3389942",
      "812mfk",
      "910dan",
      "aaradabooti",
      "admiralackbar99",
      "adrian97lol",
      "aequitaso_o",
      "aethiris",
      "afropigeon",
      "ahhhmong",
      "aizaix",
      "aka_magosh",
      "akitoalexander",
      "alex5761",
      "allenhei",
      "allou_fun_park",
      "amilton_tkm",
      "... more users that I removed...",
      "zachn17",
      "zero_x1",
      "zigslip",
      "ziirbryad",
      "zonato83",
      "zorr03body",
      "zourtv"
    ]
  }
}

As I said before, I'm using a custom library hosted on Github in order to accomplish what I needed, but for the sake of learning, I'm curious... how would I accomplish this same thing using Go's built in JSON library?

To be clear, what I'd like to do is be able to harvest the users from each JSON array embedded within the JSON object returned from the HTTP GET request. I'd also like to be able to get the list of viewers, admins, global moderators, etc., in the same way, but I figured that if I can see the moderator example using the default Go library, then reproducing that code for the other user types will be trivial.

Thank you in advance!

答案1

得分: 3

如果您只想解析出版主,可以使用以下代码:

var v struct {
    Chatters struct {
        Moderators []string
    }
}
if err := json.Unmarshal(data, &v); err != nil {
    // 处理错误
}
for _, mod := range v.Chatters.Moderators {
    fmt.Println(mod)
}

如果您想获取所有类型的聊天者,可以使用以下代码:

var v struct {
    Chatters map[string][]string
}
if err := json.Unmarshal(data, &v); err != nil {
    // 处理错误
}
for kind, users := range v.Chatters {
    for _, user := range users {
        fmt.Println(kind, user)
    }
}

在 playground 上运行代码

英文:

If you want to unmarshal moderators only, use the following:

var v struct {
	Chatters struct {
		Moderators []string
	}
}
if err := json.Unmarshal(data, &v); err != nil {
	// handle error
}
 for _, mod := range v2.Chatters.Moderators {
	fmt.Println(mod)
}

If you want to get all types of chatters, use the following:

var v struct {
	Chatters map[string][]string
}
if err := json.Unmarshal(data, &v); err != nil {
	handle error
}
for kind, users := range v1.Chatters {
	for _, user := range users {
		fmt.Println(kind, user)
	}
}

<kbd>run the code on the playground</kbd>

huangapple
  • 本文由 发表于 2015年12月21日 11:48:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/34388692.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定