2010-03-08 12 views
5

estoy trabajando con la API de Twitter, tratando de obtener los datos JSON deJSON básica> pregunta struct (usando 'ir')

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

que se parece a:

{"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\""}]}} 

Mis estructuras vistazo como:

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 
} 

y luego analizar el JSON en una variable de tipo Trending. Soy muy nuevo en JSON, así que mi principal preocupación es asegurarme de tener la estructura de datos correctamente configurada para contener los datos JSON devueltos.

Estoy escribiendo esto en 'Go' para un proyecto para la escuela. (Esto no es parte de una tarea en particular, solo estoy demostrando algo para una presentación sobre el lenguaje)

ACTUALIZACIÓN: De acuerdo con el comentario de PeterSO voy por la ruta de expresión regular. Usando:

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) 

No muestra ningún cambio. ¿Estoy especificando mal la expresión regular? Parece que 'Ir' solo permite una expresión regular a la vez ...

ACTUALIZACIÓN: ahora puede cambiar la fecha/hora a "ntrends" pero el "Unmarshaling" no está funcionando. Puedo conseguir todo lo trasladó a una interfaz que use json.Decode, pero no puedo iterar a través de él ...

Creo que mi nueva pregunta es, ¿Cómo iterar a través de:

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"]]]] 

usando "para ... range "me está dando cosas raras ...

Respuesta

2

Twitter es famoso por su Fail Whale y el Twitter API consigue un grado de error también; es horrible.

Twitter trends current Search API method respuesta puede ser expresada (usando sólo dos tendencias para simplificar los ejemplos) en forma JSON canónica, normalizado como:

{ 
    "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 fecha as_of está en el tiempo Unix, el número de segundos desde el 1/1/1970.

En Go, esto puede ser descrito por:

type Trend struct { 
    Name string 
    Query string 
} 

type Current struct { 
    As_of int64 
    Trends []Trend 
} 

Twitter Mangles la canónica, forma JSON normalizado para convertirse en:

{ 
    "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"} 
     ] 
    } 
} 

veces, Twitter devuelve esta forma JSON equivalente.

{ 
    "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": es un nombre de objeto JSON. Sin embargo, es - sin sentido - una cadena de as_of.

Si reemplazamos "2010-03-08 17:23:56": por el nombre del objeto "ntrends": (para las tendencias anidados), sobrescribiendo el redundante tiempo as_of cadena, tenemos el siguiente formulario Twitter JSON revisado:

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

Es fácil de escanear el formulario Twitter JSON para "as_of":, lea el siguiente número que el as_of tiempo Unix, y convertirlo a JSON forma de nombre por ejemplo:

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":`) 

Ahora podemos escanear el Twitter Formulario JSON para el valor aoName y reemplácelo por "ntrends": para obtener el formulario revisado JSON de Twitter.

En Go, la forma revisada Twitter JSON puede ser descrito por:

type Trend struct { 
    Name string 
    Query string 
} 

type NTrends struct { 
    NTrends []Trend 
} 

type Current struct { 
    As_of int64 
    Trends NTrends 
} 

Nota: el primer carácter de los identificadores struct y de campo están en mayúsculas para que puedan ser exportados.

He programado y probado este enfoque y parece que funciona. Como este es un proyecto escolar para ti, no he publicado mi código.

+0

Gracias Peter. FWIW No me califican en ninguno de los códigos, en realidad no escribo ningún código, solo intento mostrar las capacidades del lenguaje. Es una clase de "Teoría de los lenguajes de programación" que realmente me ha encantado. Estamos cubriendo los rieles en este momento ... – danwoods

+0

see edited OP ... – danwoods

1

Ugh, esto parece como JSON que Go no puede analizar. Twitter extrae este tipo de cosas raras todo el tiempo en su API.

El objeto 'tendencias' es un mapa de objetos de fecha a una variedad de temas de tendencia. Lamentablemente, el analizador Go JSON no es lo suficientemente inteligente como para manejar esto.

Mientras tanto, puede analizar manualmente este formato, o simplemente hacer una búsqueda de expresiones regulares para los temas.

De cualquier manera, que había puesto esto como un problema de ir a ver lo que dicen: http://code.google.com/p/go/issues/list

+0

no había pensado en analizarlo a mano, eso es lo que haré por ahora ... ¿Pero mi estructura de estructura parece correcta? – danwoods

+0

No estoy seguro de cuál sería el problema al analizarlo. La fecha se serializa como una cadena, lo que no debería causar ningún problema. Simplemente se asigna a una cadena en lugar de un objeto de fecha. –

+0

Pero, ¿acaso los nombres (las variables a la izquierda de los dos puntos en json) tienen que tener nombres de variables coincidentes en la estructura que estoy eliminando? es decir, si "\" 2010-03-08 17:23:56 "\" es un 'nombre', ¿cómo creo una variable para mantenerlo? – danwoods

1

Revisión de la respuesta anterior.

El Twitter respuesta tendencias método de búsqueda de la API está en forma conveniente JSON canónica y normalizado:

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

El Twitter Métodos API de búsqueda de las tendencias actuales, todos los días y las respuestas semanales son, sin embargo, en un JSON innecesariamente incómoda forma semejante a:

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

En clara violación de las reglas para la encapsulación de algoritmos y estructuras de datos, esto innecesariamente da a conocer que actualmente estos métodos utilizan un mapa o diccionario para su ejecución.

Para leer los datos JSON de Twitter current trends en estructuras de datos Go, utilizando el paquete json, podemos hacer algo similar a lo siguiente.

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) 
}