Próbuję odczytać dane JSON z sieci, ale ten kod zwraca pusty wynik. Nie jestem pewien, co tu robię źle.
package main
import "os"
import "fmt"
import "net/http"
import "io/ioutil"
import "encoding/json"
type Tracks struct {
Toptracks []Toptracks_info
}
type Toptracks_info struct {
Track []Track_info
Attr []Attr_info
}
type Track_info struct {
Name string
Duration string
Listeners string
Mbid string
Url string
Streamable []Streamable_info
Artist []Artist_info
Attr []Track_attr_info
}
type Attr_info struct {
Country string
Page string
PerPage string
TotalPages string
Total string
}
type Streamable_info struct {
Text string
Fulltrack string
}
type Artist_info struct {
Name string
Mbid string
Url string
}
type Track_attr_info struct {
Rank string
}
func get_content() {
// json data
url := "http://ws.audioscrobbler.com/2.0/?method=geo.gettoptracks&api_key=c1572082105bd40d247836b5c1819623&format=json&country=Netherlands"
res, err := http.Get(url)
if err != nil {
panic(err.Error())
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
panic(err.Error())
}
var data Tracks
json.Unmarshal(body, &data)
fmt.Printf("Results: %v\n", data)
os.Exit(0)
}
func main() {
get_content()
}
type WebKeys struct { Keys []struct { X5t string X5c []string } }
Nawet jeśli rzeczywiste parametry w analizowanym pliku JSON są zapisane małymi literami. Przykład JSON:{ "keys": [{ "x5t": "foo", "x5c": "baaaar" }] }
&http.Client{Timeout: 10 * time.Second}
lub używać całej innej biblioteki / strategii?json.NewDecoder(r.Body).Decode(target)
będą nie zwróci błąd dla niektórych rodzajów zniekształconego JSON! Po prostu zmarnowałem kilka godzin, próbując zrozumieć, dlaczego ciągle otrzymuję pustą odpowiedź - okazuje się, że źródłowy JSON miał dodatkowy przecinek w miejscu, w którym nie powinien. Proponujęjson.Unmarshal
zamiast tego użyć . Jest też dobry opis o innych potencjalnych niebezpieczeństwach związanych z używaniemjson.Decoder
tutajTwoim problemem były deklaracje wycinków w twoich danych
structs
(poza tymTrack
, że nie powinny to być wycinki ...). Zostało to spotęgowane przez niektóre raczej głupie nazwy pól w pobranym pliku json, które można naprawić za pomocą tagów strukturalnych, patrz godoc .Poniższy kod pomyślnie przeanalizował plik JSON. Jeśli masz dalsze pytania, daj mi znać.
package main import "fmt" import "net/http" import "io/ioutil" import "encoding/json" type Tracks struct { Toptracks Toptracks_info } type Toptracks_info struct { Track []Track_info Attr Attr_info `json: "@attr"` } type Track_info struct { Name string Duration string Listeners string Mbid string Url string Streamable Streamable_info Artist Artist_info Attr Track_attr_info `json: "@attr"` } type Attr_info struct { Country string Page string PerPage string TotalPages string Total string } type Streamable_info struct { Text string `json: "#text"` Fulltrack string } type Artist_info struct { Name string Mbid string Url string } type Track_attr_info struct { Rank string } func perror(err error) { if err != nil { panic(err) } } func get_content() { url := "http://ws.audioscrobbler.com/2.0/?method=geo.gettoptracks&api_key=c1572082105bd40d247836b5c1819623&format=json&country=Netherlands" res, err := http.Get(url) perror(err) defer res.Body.Close() decoder := json.NewDecoder(res.Body) var data Tracks err = decoder.Decode(&data) if err != nil { fmt.Printf("%T\n%s\n%#v\n",err, err, err) switch v := err.(type){ case *json.SyntaxError: fmt.Println(string(body[v.Offset-40:v.Offset])) } } for i, track := range data.Toptracks.Track{ fmt.Printf("%d: %s %s\n", i, track.Artist.Name, track.Name) } } func main() { get_content() }
źródło
Potrzebujesz nazw właściwości pisanych dużymi literami w swoich strukturach, aby mogły być używane przez pakiety json.
Nazwy właściwości pisane dużymi literami to
exported properties
. Nazwy właściwości pisane małymi literami nie są eksportowane.Musisz również przekazać obiekt danych przez referencję (
&data
).package main import "os" import "fmt" import "net/http" import "io/ioutil" import "encoding/json" type tracks struct { Toptracks []toptracks_info } type toptracks_info struct { Track []track_info Attr []attr_info } type track_info struct { Name string Duration string Listeners string Mbid string Url string Streamable []streamable_info Artist []artist_info Attr []track_attr_info } type attr_info struct { Country string Page string PerPage string TotalPages string Total string } type streamable_info struct { Text string Fulltrack string } type artist_info struct { Name string Mbid string Url string } type track_attr_info struct { Rank string } func get_content() { // json data url := "http://ws.audioscrobbler.com/2.0/?method=geo.gettoptracks&api_key=c1572082105bd40d247836b5c1819623&format=json&country=Netherlands" res, err := http.Get(url) if err != nil { panic(err.Error()) } body, err := ioutil.ReadAll(res.Body) if err != nil { panic(err.Error()) } var data tracks json.Unmarshal(body, &data) fmt.Printf("Results: %v\n", data) os.Exit(0) } func main() { get_content() }
źródło
Wyniki z
json.Unmarshal
(dovar data interface{}
) nie pasują bezpośrednio do typu Go i deklaracji zmiennych. Na przykład,package main import ( "encoding/json" "fmt" "io/ioutil" "net/http" "os" ) type Tracks struct { Toptracks []Toptracks_info } type Toptracks_info struct { Track []Track_info Attr []Attr_info } type Track_info struct { Name string Duration string Listeners string Mbid string Url string Streamable []Streamable_info Artist []Artist_info Attr []Track_attr_info } type Attr_info struct { Country string Page string PerPage string TotalPages string Total string } type Streamable_info struct { Text string Fulltrack string } type Artist_info struct { Name string Mbid string Url string } type Track_attr_info struct { Rank string } func get_content() { // json data url := "http://ws.audioscrobbler.com/2.0/?method=geo.gettoptracks&api_key=c1572082105bd40d247836b5c1819623&format=json&country=Netherlands" url += "&limit=1" // limit data for testing res, err := http.Get(url) if err != nil { panic(err.Error()) } body, err := ioutil.ReadAll(res.Body) if err != nil { panic(err.Error()) } var data interface{} // TopTracks err = json.Unmarshal(body, &data) if err != nil { panic(err.Error()) } fmt.Printf("Results: %v\n", data) os.Exit(0) } func main() { get_content() }
Wynik:
Results: map[toptracks:map[track:map[name:Get Lucky (feat. Pharrell Williams) listeners:1863 url:http://www.last.fm/music/Daft+Punk/_/Get+Lucky+(feat.+Pharrell+Williams) artist:map[name:Daft Punk mbid:056e4f3e-d505-4dad-8ec1-d04f521cbb56 url:http://www.last.fm/music/Daft+Punk] image:[map[#text:http://userserve-ak.last.fm/serve/34s/88137413.png size:small] map[#text:http://userserve-ak.last.fm/serve/64s/88137413.png size:medium] map[#text:http://userserve-ak.last.fm/serve/126/88137413.png size:large] map[#text:http://userserve-ak.last.fm/serve/300x300/88137413.png size:extralarge]] @attr:map[rank:1] duration:369 mbid: streamable:map[#text:1 fulltrack:0]] @attr:map[country:Netherlands page:1 perPage:1 totalPages:500 total:500]]]
źródło