Golang Go语言中json的键重复问题
Golang Go语言中json的键重复问题
最近在写个 steam 的第三方 api,其中有个接口是返回当前联赛中的比赛详细资料。url 是下面这个:
https://api.steampowered.com/IDOTA2Match_570/GetLiveLeagueGames/v1?key=<apikey>
但它返回的 json 里英雄描述技能升级的 key 是重复的,这个应该是不符合 json 编码标准的吧(没想到浓眉大眼的沃尔沃也干了),例如下:
"abilities":[ // <-这样的"abilities"键总共有 5 个(代表 5 个英雄的技能升级情况)
{
"ability_id":5106, //唯一技能 ID
"ability_level":2 //技能等级
},
{
"ability_id":5107,
"ability_level":3
}
]
,
"abilities":[
{
"ability_id":5082,
"ability_level":3
},
{
"ability_id":5083,
"ability_level":2
}
]
,
"abilities":[
{
"ability_id":5122,
"ability_level":3
},
{
"ability_id":5123,
"ability_level":2
},
{
"ability_id":5125,
"ability_level":1
}
]
我尝试在结构体里用相同的 json tag 指定不同的字段但自带的 json 包好像解析不出来,求知道的大佬指点下。
Abilities1 []struct {
AbilityID uint16 `json:"ability_id"`
AbilityLevel uint8 `json:"ability_level"`
} `json:"abilities"`
Abilities2 []struct {
AbilityID uint16 `json:"ability_id"`
AbilityLevel uint8 `json:"ability_level"`
} `json:"abilities"`
更多关于Golang Go语言中json的键重复问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
这都不是合法的 JSON,解析后就直接最后一个把上面的全覆盖了。
你把这段 JSON 复制粘贴到这个网站试试,用的是 js 原生的 JSON.parse 解析
http://apijson.org/
更多关于Golang Go语言中json的键重复问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
这个反爬虫 666 !
如果是动态语言,简单字符串替换下把abilities
替换为 abilities__<index_num>
然后就可以处理了,
golang 这种碰到就难搞了
是的,确认了的确不符合规范,但不知道 valve 这样做的用意是啥
估计就不是按照 application/json 格式返回的,可能是 text/plain 这种
dota2 ?
这个是不是考虑自己先把 json 字符串特殊处理一下呢?
比如,trim 后直接把 "abilities":
全 remove 掉,然后用 []
括起来。
动态语言下的替换指的是正则匹配后替换还是,有思路的话 golang 应该实现也没问题。
主要是询问有没有碰到过或者见过第三方 json 库支持这种情况的。
这种用遍历 Token 自己搞吧
是按照 json 返回的,它有个?format=xxx 参数,不指定的话就返回 json,参考网站:
http://steamwebapi.azurewebsites.net/
那就很奇怪了,它的库有问题啊,居然支持在同一层级有同名的 key,或者压根就没用 JSON 库解析过,直接拼出来字符串返回
字符串替换都可以。
golang 你也手动替换成合法的 json 吧,
1. 把第一个"abilities":[
替换为 "abilities":[[
2. 把最后一个"ability_level":1}]
替换为 "ability_level":1}]]
3. 把剩下的 "abilities":[
替换为 [
key 要去 steam 申请的,随便填应该会返回一个 forbidden 页面,所以是 html 格式,在 chrome 里可以直接看到:<br>Forbidden<br>Access is denied. Retrying will not help. Please verify your<br>key=<br>parameter.<br>
最外层是个数组吗?
dota2 ! 我记得有个 opendota 和 varendata 的
是的,以单场比赛为单位,json 附在 append 里了
是的,应该都是从 apisteam 里取得数据
都不在同一层级, 有啥问题? 哪重复了?
一个在 “radiant” 节点下, 一个在 “dire” 节点下.
类似于下面这样, 你能说下面的 hello
是重复键?<br>{<br>"a": {<br> "hello": 123<br>},<br><br>"b": {<br> "hello": 456<br>}<br>}<br>
https://imgur.com/a/sLZdgW1
这个我知道,一般只要 Request 能到达接口,处理后业务错误也应该返回和正确结果格式一致的 Response。
它既然都提示 key 有问题了,就说明已经经过接口处理过了。
每个 team 下都有 5 个 abilities 键
看看你用的 json 库有没有 sax 的接口,这种一般可行
你在 github 上发的那个数据, 并没有你说的这种情况.
不好意思, 看错了, 是我的那个 Chrome 插件解析之后,只剩 4 个了, 查看 原始的数据的时候, 里面是有很多个.
拿到 json 之后先别解析,将五个"abilities"字符串依次替换成"abilities0",“abilities1”…再解析
有个东西叫
json-to-go
https://mholt.github.io/json-to-go/
type AutoGenerated struct {
Abilities []struct {
AbilityID int json:"ability_id"
AbilityLevel int json:"ability_level"
} json:"abilities"
}
https://github.com/buger/jsonparser
这种库可以处理这个问题。
谢谢,这个工具不错,但刚才试了这种写法还是只会解析最后一组 abilities 数据。
这个不难处理,用标准库就行,稍微加点技巧
https://gist.github.com/reusee/2cf9de7bbf46e6049a798630002db54b
就是用 json.Decoder.Token 方法把 “abilities” 读掉,然后用 Decode 方法解码后面的数组,直到 Token 返回 ‘}’
在Golang(Go语言)中处理JSON数据时,遇到键重复的问题是比较少见的,因为标准的JSON格式规范要求键是唯一的。然而,如果你确实遇到或需要处理含有重复键的非标准JSON数据,这里有一些处理方式:
-
解析为map[string]interface{}: Go的
encoding/json
包在解析JSON到map[string]interface{}
时,如果遇到重复键,后面的值会覆盖前面的值。这意味着最终map中只保留最后一个键对应的值。 -
使用自定义解析器: 如果你需要保留所有重复键的值(例如,存储为数组或切片),你可以实现一个自定义的UnmarshalJSON方法。这通常涉及到先将JSON解析为原始的字节数组或
[]byte
,然后手动解析这些字节来捕获所有键和值。 -
使用第三方库: 有些第三方库可能提供了更灵活的处理重复键的方法。这些库可能允许你定义自定义的解析行为,比如将重复键的值收集到切片中。
-
预处理JSON: 如果可能,最好在JSON数据到达你的应用之前就解决键重复的问题。这可以通过修改生成JSON数据的源头或使用一个中间步骤来预处理JSON数据。
总之,标准的Go JSON处理库不支持直接处理重复键的情况,但你可以通过自定义解析逻辑或使用第三方库来实现这一需求。在大多数情况下,确保JSON数据的键是唯一的,是避免此类问题的最佳实践。