2010-03-08 6 views
5

Je travaille avec l'api de twitter, en essayant d'obtenir les données JSON deJSON de base> question struct (en utilisant 'Go')

http://search.twitter.com/trends/current.json 

qui ressemble à:

{"as_of":1268069036,"trends":{"2010-03-08 17:23:56":[{"name":"Happy Women's Day","query":"\"Happy Women's Day\" OR \"Women's Day\""},{"name":"#MusicMonday","query":"#MusicMonday"},{"name":"#MM","query":"#MM"},{"name":"Oscars","query":"Oscars OR #oscars"},{"name":"#nooffense","query":"#nooffense"},{"name":"Hurt Locker","query":"\"Hurt Locker\""},{"name":"Justin Bieber","query":"\"Justin Bieber\""},{"name":"Cmon","query":"Cmon"},{"name":"My World 2","query":"\"My World 2\""},{"name":"Sandra Bullock","query":"\"Sandra Bullock\""}]}} 

Mon struct regard comme:

type trend struct { 
name string 
query string 
} 

type trends struct { 
id string 
arr_of_trends []trend 
} 

type Trending struct { 
as_of string 
trends_obj trends 
} 

puis je parse la JSON dans une variable de type Trending. Je suis très nouveau dans JSON, donc ma principale préoccupation est de m'assurer que la structure de données est correctement configurée pour contenir les données renvoyées par JSON. J'écris ceci dans 'Go' pour un projet pour l'école. (Cela ne fait pas partie d'une mission particulière, juste quelque chose que je démo-pour une présentation sur la langue)

MISE À JOUR: Conformément au commentaire de PeterSO je vais la voie de l'expression rationnelle. Utilisation:

Cur_Trends := new(Current) 
/* unmarshal the JSON into our structures */ 

//find proper json time-name 
aoUnixTime, _, _ := os.Time() 

// insert code to find and convert as_of Unix time to aoUnixTime 
    aoName := time.SecondsToUTC(aoUnixTime).Format(`"2006-01-02"`) 
    fmt.Printf("%s\n", aoName) 
    regexp_pattern := "/" + aoName + "/" 
    regex, _ := regexp.Compile(regexp_pattern); 

    cleaned_json := regex.ReplaceAllString(string(body2), "ntrends") 
    os.Stdout.WriteString(cleaned_json) 

N'affiche aucun changement. Est-ce que je spécifie l'expression rationnelle incorrecte? Il semble que 'Go' n'autorise qu'une seule regexp à la fois ...

MISE À JOUR: peut maintenant changer la date/heure en "ntrends" mais le "Unmarshaling" ne fonctionne pas. Je peux tout déplacé dans une interface à l'aide json.Decode, mais ne peut pas itérer à travers elle ...

Je pense que ma nouvelle question est: Comment puis-je itérer:

map[as_of:1.268176902e+09 trends:map[ntrends:[map[name:#nowplaying query:#nowplaying] map[name:#imtiredofseeing query:#imtiredofseeing] map[name:#iWillNever query:#iWillNever] map[name:#inmyfamily query:#inmyfamily] map[name:#raiseyourhandif query:#raiseyourhandif] map[name:#ripbig query:#ripbig] map[name:QVC query:QVC] map[name:#nooffense query:#nooffense] map[name:#RIPLaylaGrace query:#RIPLaylaGrace] map[name:Justin Bieber query:"Justin Bieber"]]]] 

en utilisant « pour ... range "me donne des choses étranges ...

Répondre

2

Twitter est célèbre pour son Fail Whale, et le Twitter API obtient une note d'échec aussi; c'est horrible.

Twitter réponse trends current Search API method peut être exprimé (en utilisant seulement deux tendances pour simplifier les exemples) sous forme JSON canonique, normalisée:

{ 
    "as_of":1268069036, 
    "trends":[ 
     {"name":"Happy Women's Day","query":"\"Happy Women's Day\" OR \"Women's Day\""}, 
     {"name":"#MusicMonday","query":"#MusicMonday"},{"name":"#MM","query":"#MM"} 
    ] 
} 

La date as_of est dans le temps Unix, le nombre de secondes écoulées depuis le 1/1/1970.

Dans Go, cela peut être décrit par:

type Trend struct { 
    Name string 
    Query string 
} 

type Current struct { 
    As_of int64 
    Trends []Trend 
} 

Twitter Mangles canonique, sous forme de JSON normalisée pour devenir:

{ 
    "as_of":1268069036, 
    "trends":{ 
     "2010-03-08 17:23:56":[ 
      {"name":"Happy Women's Day","query":"\"Happy Women's Day\" OR \"Women's Day\""}, 
      {"name":"#MusicMonday","query":"#MusicMonday"} 
     ] 
    } 
} 

Parfois, Twitter renvoie ce formulaire équivalent JSON.

{ 
    "trends":{ 
     "2010-03-08 17:23:56":[ 
      {"name":"Happy Women's Day","query":"\"Happy Women's Day\" OR \"Women's Day\""}, 
      {"name":"#MusicMonday","query":"#MusicMonday"} 
     ] 
    }, 
    "as_of":1268069036 
} 

"2010-03-08 17:23:56": est un nom d'objet JSON. Cependant, c'est - sans le vouloir - une forme de chaîne de as_of.

Si nous remplaçons "2010-03-08 17:23:56": par le nom de l'objet "ntrends": (pour les tendances imbriquées), en remplaçant le temps de chaîne as_of redondante, nous avons la forme révisée Twitter JSON suivant:

{ 
    "as_of":1268069036, 
    "trends":{ 
     "ntrends":[ 
      {"name":"Happy Women's Day","query":"\"Happy Women's Day\" OR \"Women's Day\""}, 
      {"name":"#MusicMonday","query":"#MusicMonday"} 
     ] 
    } 
} 

Il est facile de scanner le formulaire Twitter JSON pour "as_of":, lisez le numéro suivant que le temps Unix as_of, et le convertir en forme de nom JSON par exemple:

var aoUnixTime int64 
// insert code to find and convert as_of Unix time to aoUnixTime 
aoName := time.SecondsToUTC(aoUnix).Format(`"2006-01-02 15:04:05":`) 

maintenant, nous pouvons analyser le Twitter Formulaire JSON pour la valeur aoName et remplacez-le par "ntrends": pour obtenir le formulaire JSON Twitter révisé.

Dans Go, peut être décrit par le formulaire Twitter JSON révisé:

type Trend struct { 
    Name string 
    Query string 
} 

type NTrends struct { 
    NTrends []Trend 
} 

type Current struct { 
    As_of int64 
    Trends NTrends 
} 

Note: le premier caractère des identifiants de struct et sur le terrain sont en majuscules afin qu'ils puissent être exportés.

J'ai programmé et testé cette approche et cela semble fonctionner. Puisque c'est un projet d'école pour vous, je n'ai pas publié mon code.

+0

Merci Peter. FWIW Je ne reçois aucune note sur le code, je n'écris actuellement aucun code, essayant simplement de montrer les capacités du langage. C'est pour un cours de "Théorie des langages de programmation" que j'ai vraiment aimé. Nous couvrons les rails en ce moment ... – danwoods

+0

voir édité OP ... – danwoods

1

Ugh, cela semble comme JSON que Go ne peut pas analyser. Twitter tire ce genre de choses bizarre tout le temps dans leur API.

L'objet 'trends' est une carte d'objets de date vers un tableau de sujets tendance. Malheureusement, l'analyseur Go JSON n'est pas assez intelligent pour gérer cela.

En attendant, vous pouvez analyser ce format manuellement ou effectuer une recherche d'expression régulière pour les sujets.

De toute façon, je poste cela comme un problème Allez voir ce qu'ils disent: http://code.google.com/p/go/issues/list

+0

n'avait pas pensé à l'analyser à la main, c'est ce que je ferai pour l'instant ... Mais ma structure de structure semble correcte? – danwoods

+0

Je ne sais pas quel serait le problème avec l'analyse. La date est sérialisée en tant que chaîne, ce qui ne devrait pas causer de problèmes. Il ne fait que correspondre à une chaîne au lieu d'un objet date. –

+0

Mais les noms (les variables sur la gauche du deux-points dans le json) ne doivent-ils pas avoir des noms de variables correspondants dans la structure que je suis en train de déballer? ie: si "\" 2010-03-08 17:23:56 "\" est un 'nom', comment puis-je créer une variable pour le contenir? – danwoods

1

Révision à une réponse antérieure.

Le Twitter réponse Recherche des tendances de la méthode API est sous forme JSON canonique et normalisée pratique:

{"trends":[{"name":"#amazonfail","url":"http:\/\/search.twitter.com\/search?q=%23amazonfail"},... truncated ...],"as_of":"Mon, 13 Apr 2009 20:48:29 +0000"} 

Le courant Twitter Search API Méthodes tendances, les réponses quotidiennes et hebdomadaires sont, cependant, dans un JSON inutilement pratique une forme similaire à:

{"trends":{"2009-03-19 21:00":[{"query":"AIG","name":"AIG"},... truncated ...],... truncated ...},"as_of":1239656409} 

En violation flagrante des règles pour l'encapsulation des structures d'algorithmes et de données, ce révèle inutilement qu'actuellement ces méthodes utilisent une carte ou un dictionnaire pour leur mise en œuvre.

Pour lire les données JSON à partir de Twitter current trends dans Go structures de données, en utilisant le package json, nous pouvons faire quelque chose de similaire à ce qui suit.

package main 

import (
    "fmt" 
    "json" 
) 

type Trend struct { 
    Name string 
    Query string 
} 

type Current struct { 
    As_of int64 
    Trends map[string][]Trend 
} 

var currentTrends = `{"as_of":1268069036,"trends":{"2010-03-08 17:23:56":[{"name":"Happy Women's Day","query":"\"Happy Women's Day\" OR \"Women's Day\""},{"name":"#MusicMonday","query":"#MusicMonday"},{"name":"#MM","query":"#MM"},{"name":"Oscars","query":"Oscars OR #oscars"},{"name":"#nooffense","query":"#nooffense"},{"name":"Hurt Locker","query":"\"Hurt Locker\""},{"name":"Justin Bieber","query":"\"Justin Bieber\""},{"name":"Cmon","query":"Cmon"},{"name":"My World 2","query":"\"My World 2\""},{"name":"Sandra Bullock","query":"\"Sandra Bullock\""}]}}` 

func main() { 
    var ctJson = currentTrends 
    var ctVal = Current{} 
    ok, errtok := json.Unmarshal(ctJson, &ctVal) 
    if !ok { 
     fmt.Println("Unmarshal errtok: ", errtok) 
    } 
    fmt.Println(ctVal) 
}