2012-06-18 10 views
5

Sto prelevando i dati da remoto JSON a http://hndroidapi.appspot.com/news/format/json/page/?appid=test. Il problema che sto incontrando è che questa API sembra costruire il JSON senza gestire correttamente la codifica UTF-8 (correggimi se ho torto qui). Ad esempio, parte del risultato che viene passato in questo momento èGestione di UTF-8 non valido da json, in ruby ​​

{ 
"title":"IPad - please don€™t ding while you and I are asleep ", 
"url":"http://modern-products.tumblr.com/post/25384729998/ipad-please-dont-ding-while-you-and-i-are-asleep", 
"score":"10 points", 
"user":"roee", 
"comments":"18 comments", 
"time":"1 hour ago", 
"item_id":"4128497", 
"description":"10 points by roee 1 hour ago | 18 comments" 
} 

Avviso del don€™t. E questo non è l'unico tipo di personaggio a cui sta soffocando. C'è qualcosa che posso fare per convertire i dati in qualcosa di pulito, dato che non controllo l'API?

Edit:

Ecco come sto tirando giù il JSON:

hn_url = "http://hndroidapi.appspot.com/news/format/json/page/?appid=test" 
    url = URI.parse(hn_url) 

    # Attempt to get the json 
    req = Net::HTTP::Get.new(hn_url) 
    req.add_field('User-Agent', 'Test') 
    res = Net::HTTP.start(url.host, url.port) {|http| http.request(req) } 
    response = res.body 
    if response.nil? 
    puts "Bad response when fetching HN json" 
    return 
    end 

    # Attempt to parse the json 
    result = JSON.parse(response) 
    if result.nil? 
    puts "Error parsing HN json" 
    return 
    end 

Edit 2:

appena trovato la pagina GitHub del API. Sembra che questo sia un problema eccezionale. Ancora non è sicuro se ci sono soluzioni alternative che posso fare dal mio fine: https://github.com/glebpopov/Hacker-News-Droid-API/issues/4

+0

Sembra che il corpo di risposta JSON che si sta ricevendo possa includere simboli HTML-safe. Non vedo nessun cattivo carattere a prima vista, e vedo che l'intestazione di risposta Content-Type è impostata su 'application/json; charset = utf-8', che sembra corretto. Come stai ottenendo il corpo della risposta? Vorrei provare ad esaminare la risposta con uno strumento del browser come "Dev HTTP Client" o CURL, e vedere se l'applicazione sta diventando diversa dalla risposta effettiva. In tal caso, potresti gestirlo in modo errato nel tuo codice. –

+0

Grazie. Ho aggiunto il mio codice nella modifica. Il problema, tuttavia, è che sono simboli HTML-safe. Ma non dovrebbe essere un simbolo dell'euro e un simbolo "tm". Dovrebbe essere un apostrofo. – hodgesmr

+0

È possibile visualizzare la risposta esatta nella console utilizzando 'puts res.body'. Stai vedendo i simboli funky in seguito tramite l'oggetto 'result'? –

risposta

4

Sembra che il corpo della risposta JSON si ricevono viene ricevuto in US-ASCII invece di UTF-8 perché Net::HTTP non lo fa di proposito forzare la codifica.

1.9.3p194 :044 > puts res.body.encoding 
US-ASCII 

In Ruby 1.9.3, è possibile forzare la codifica se si sa cosa si suppone essere. Prova questo:

response = res.body.force_encoding('UTF-8') 

Il parser JSON deve quindi gestire l'UTF-8 nel modo desiderato.

Riferimenti

1

Uso force_encoding sembra la soluzione migliore. In seguito alla risposta di Kevin Dickerson, ecco una spiegazione della stranezza.

Net::HTTP è una specie di confusione.

On 1.9.3:

  • Se il server invia una risposta chunked, devi sempre avere ASCII-8BIT. Questo sembra avere la precedenza sugli altri scenari.
  • Se si chiama http.request con un oggetto Get, si otterrà US-ASCII. Questo metodo non esegue la compressione per te.
  • Se si chiama http.get, la compressione è abilitata.
    • se il server supporta la compressione, si otterrebbe ASCII-8BIT
    • se il server non invia un corpo compressa, si otterrebbe US-ASCII

Faresti ottieni US-ASCII perché quando Net::HTTP crea la stringa del buffer per ricevere la risposta, viene creata nella codifica del file di origine predefinito dell'interprete, che è US-ASCII. (I file di origine net/, non hanno il commento di codifica in alto, in modo da utilizzare di default di Ruby.)

La decompressione produce ASCII-8BIT perché è codificato per farlo nel metodo get durante la decompressione.

Su 2.0, sembra che tu riceva sempre UTF-8, ma questo è perché è la codifica del file di origine predefinita. Se lo si modifica tramite l'opzione -K, la codifica della risposta cambierà di conseguenza. Prova a passare n, e, s, u a -K.

Problemi correlati