使用Steam Rest API与JSON 使用Steam Rest API与JSON进行交互。

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

Using Steam Rest API with JSON

问题

我目前正在进行一个关于Golang的教育项目,使用Steam RESTAPI来获取玩家的反恐精英(CS:GO)库存。

经过数小时的努力,我已经取得了以下进展:

1)调用包含用户ID的URL请求会返回一个带有他们库存的JSON消息(但JSON有点棘手,这是我遇到的问题)。

2)我需要循环遍历JSON的rgDescriptions部分。

3)我已经构建了以下代码(位于下方),它循环遍历rgDescription,但是我不确定如何获取其中的所有值。

代码:

var data map[string]interface{}
r, err := myClient.Get("http://steamcommunity.com/profiles/" + id + "/inventory/json/730/2")
detectErr(err)
defer r.Body.Close()

result, err := ioutil.ReadAll(r.Body)
detectErr(err)

err = json.Unmarshal(result, &data)
detectErr(err)
myMap := data["rgDescriptions"]
v := reflect.ValueOf(myMap)
for _, key := range v.MapKeys() {
    value := v.MapIndex(key)
    fmt.Println(key, "-", value)
    //fmt.Println(reflect.ValueOf(value).MapIndex(varr[0])) // My idea for making this entire thing work, however it just spits out an error instead. :(
    fmt.Println("----------------\n")
}

以上代码会打印出类似以下内容:

1432174707_0 - map[classid:1432174707 market_hash_name:Revolver Case background_color: market_tradable_restriction:7 tags:[map[category_name:Type internal_name:CSGO_Type_WeaponCase name:Container category:Type] map[name:The Revolver Case Collection category:ItemSet category_name:Collection internal_name:set_community_10] map[internal_name:normal name:Normal category:Quality category_name:Category] map[category:Rarity color:b0c3d9 category_name:Quality internal_name:Rarity_Common name:Base Grade]] appid:730 instanceid:0 icon_url:-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXU5A1PIYQNqhpOSV-fRPasw8rsUFJ5KBFZv668FFYwnfKfcG9HvN7iktaOkqD1auLTxD5SvZYgiLvFpo7xjVLh-kdrYWnzcoGLMlhpsyM-5vg market_name:Revolver Case type:Base Grade Container marketable:1 commodity:1 icon_drag_url: name:Revolver Case name_color:D2D2D2 tradable:1 descriptions:[map[type:html value: ] map[type:html value:Container Series #111 color:99ccff] map[type:html value: ] map[type:html value:Contains one of the following:] map[type:html value:R8 Revolver | Crimson Web color:4b69ff] map[type:html value:AUG | Ricochet color:4b69ff] map[type:html value:Desert Eagle | Corinthian color:4b69ff] map[value:P2000 | Imperial color:4b69ff type:html] map[type:html value:Sawed-Off | Yorick color:4b69ff] map[color:4b69ff type:html value:SCAR-20 | Outbreak] map[type:html value:PP-Bizon | Fuel Rod color:8847ff] map[type:html value:Five-SeveN | Retrobution color:8847ff] map[type:html value:Negev | Power Loader color:8847ff] map[type:html value:SG 553 | Tiger Moth color:8847ff] map[type:html value:Tec-9 | Avalanche color:8847ff] map[type:html value:XM1014 | Teclu Burner color:8847ff] map[type:html value:AK-47 | Point Disarray color:d32ce6] map[type:html value:G3SG1 | The Executioner color:d32ce6] map[type:html value:P90 | Shapewood color:d32ce6] map[type:html value:M4A4 | Royal Paladin color:eb4b4b] map[type:html value:R8 Revolver | Fade color:eb4b4b] map[value:or an Exceedingly Rare Special Item! color:ffd700 type:html] map[type:html value: ] map[color:00a000 app_data:map[limited:1] type:html value:]]]

如果你想看一下我收到的JSON的示例,这是一个示例URL:http://steamcommunity.com/profiles/76561198096365603/inventory/json/730/2

因此,总结一下,我需要找出如何循环遍历value变量的内容。

非常感谢任何帮助。
谢谢。

英文:

I'm currently working on an educational project regarding Golang and using the Steam RESTAPI to retrieve a player's CounterStrike (CS:GO) inventory.

After spending numerous hours this is the progress I have been able to gain:

  1. Calling a request to a url containing the users ID returns a JSON message with their inventory (but the JSON is a little tricky and is what I'm having trouble on).

  2. I need to loop through the rgDescriptions section of the JSON.

  3. I have constructed the following code (located lower down) that loops through the rgDescription, however I am unsure how to then get the value of everything inside of it.

The code:

var data map[string]interface{}
r, err := myClient.Get("http://steamcommunity.com/profiles/" + id + "/inventory/json/730/2")
detectErr(err)
defer r.Body.Close()

result, err := ioutil.ReadAll(r.Body)
detectErr(err)

err = json.Unmarshal(result, &data)
detectErr(err)
myMap := data["rgDescriptions"]
v := reflect.ValueOf(myMap)
for _, key := range v.MapKeys() {
	value := v.MapIndex(key)
	fmt.Println(key, "-", value)
	//fmt.Println(reflect.ValueOf(value).MapIndex(varr[0])) // My idea for making this entire thing work, however it just spits out an error instead. :(
	fmt.Println("----------------\n")
}

The code above prints out something along the lines of:

1432174707_0 - map[classid:1432174707 market_hash_name:Revolver Case background_color: market_tradable_restriction:7 tags:[map[category_name:Type internal_name:CSGO_Type_WeaponCase name:Container category:Type] map[name:The Revolver Case Collection category:ItemSet category_name:Collection internal_name:set_community_10] map[internal_name:normal name:Normal category:Quality category_name:Category] map[category:Rarity color:b0c3d9 category_name:Quality internal_name:Rarity_Common name:Base Grade]] appid:730 instanceid:0 icon_url:-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXU5A1PIYQNqhpOSV-fRPasw8rsUFJ5KBFZv668FFYwnfKfcG9HvN7iktaOkqD1auLTxD5SvZYgiLvFpo7xjVLh-kdrYWnzcoGLMlhpsyM-5vg market_name:Revolver Case type:Base Grade Container marketable:1 commodity:1 icon_drag_url: name:Revolver Case name_color:D2D2D2 tradable:1 descriptions:[map[type:html value: ] map[type:html value:Container Series #111 color:99ccff] map[type:html value: ] map[type:html value:Contains one of the following:] map[type:html value:R8 Revolver | Crimson Web color:4b69ff] map[type:html value:AUG | Ricochet color:4b69ff] map[type:html value:Desert Eagle | Corinthian color:4b69ff] map[value:P2000 | Imperial color:4b69ff type:html] map[type:html value:Sawed-Off | Yorick color:4b69ff] map[color:4b69ff type:html value:SCAR-20 | Outbreak] map[type:html value:PP-Bizon | Fuel Rod color:8847ff] map[type:html value:Five-SeveN | Retrobution color:8847ff] map[type:html value:Negev | Power Loader color:8847ff] map[type:html value:SG 553 | Tiger Moth color:8847ff] map[type:html value:Tec-9 | Avalanche color:8847ff] map[type:html value:XM1014 | Teclu Burner color:8847ff] map[type:html value:AK-47 | Point Disarray color:d32ce6] map[type:html value:G3SG1 | The Executioner color:d32ce6] map[type:html value:P90 | Shapewood color:d32ce6] map[type:html value:M4A4 | Royal Paladin color:eb4b4b] map[type:html value:R8 Revolver | Fade color:eb4b4b] map[value:or an Exceedingly Rare Special Item! color:ffd700 type:html] map[type:html value: ] map[color:00a000 app_data:map[limited:1] type:html value:]]]

If you'd like to see an example of the JSON I am receiving here is an example URL. http://steamcommunity.com/profiles/76561198096365603/inventory/json/730/2

So in conclusion, I need to figure out how to loop through the contents of the value variable.

Any help would be greatly appreciated.
Thank you.

答案1

得分: 4

以下是一个工作示例。关键是声明一个与你的JSON匹配的结构类型。

由于键不一致,你需要使用map类型来表示item。

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
)

type Inventory struct {
	Success      bool                    `json:"success"`
	Items        map[string]*Item        `json:"rgInventory"`
	Descriptions map[string]*Description `json:"rgDescriptions"`
}

type Item struct {
	ID         string `json:"id"`
	ClassID    string `json:"classid"`
	InstanceID string `json:"instanceid"`
	Amount     string `json:"amount"`
	Pos        int    `json:"pos"`
}

type Description struct {
	Descriptions []struct {
		Value string `json:"value"`
	} `json:"descriptions"`
}

func main() {
	res, err := http.Get("http://steamcommunity.com/profiles/76561198096365603/inventory/json/730/2")
	if err != nil {
		log.Fatal(err)
	}

	inventory := &Inventory{}
	if err := json.NewDecoder(res.Body).Decode(&inventory); err != nil {
		log.Fatal(err)
	}

	for _, item := range inventory.Descriptions {
		for _, d := range item.Descriptions {
			fmt.Printf(d.Value)
		}
	}
}

希望对你有帮助!

英文:

Below is a working example. The crux is to declare a struct type that matches your JSON.

You need to use a map type for your item since the key is not consistent.

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
)

type Inventory struct {
	Success      bool                    `json:"success"`
	Items        map[string]*Item        `json:"rgInventory"`
	Descriptions map[string]*Description `json:"rgDescriptions"`
}

type Item struct {
	ID         string `json:"id"`
	ClassID    string `json:"classid"`
	InstanceID string `json:"instanceid"`
	Amount     string `json:"amount"`
	Pos        int    `json:"pos"`
}

type Description struct {
	Descriptions []struct {
		Value string `json:"value"`
	} `json:"descriptions"`
}

func main() {
	res, err := http.Get("http://steamcommunity.com/profiles/76561198096365603/inventory/json/730/2")
	if err != nil {
		log.Fatal(err)
	}

	inventory := &Inventory{}
	if err := json.NewDecoder(res.Body).Decode(&inventory); err != nil {
		log.Fatal(err)
	}

	for _, item := range inventory.Descriptions {
		for _, d := range item.Descriptions {
			fmt.Printf(d.Value)
		}
	}
}

huangapple
  • 本文由 发表于 2017年7月25日 05:12:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/45290144.html
匿名

发表评论

匿名网友

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

确定