2012-06-01 6 views
26

Solo cercando di testare comandi JSON Python molto semplici, ma ho qualche problema.Usa "oggetto tipo byte" da urlopen.read con JSON?

urlopen('http://www.similarsitesearch.com/api/similar/ebay.com').read() 

dovrebbero uscita

'{"num":20,"status":"ok","r0":"http:\\/\\/www.propertyroom.com\\/","r1":"http:\\/\\/www.ubid.com\\/","r2":"http:\\/\\/www.bidcactus.com\\/","r3":"http:\\/\\/www.etsy.com\\/","r4":"http:\\/\\/us.ebid.net\\/","r5":"http:\\/\\/www.bidrivals.com\\/","r6":"http:\\/\\/www.ioffer.com\\/","r7":"http:\\/\\/www.shopgoodwill.com\\/","r8":"http:\\/\\/www.beezid.com\\/","r9":"http:\\/\\/www.webidz.com\\/","r10":"http:\\/\\/www.auctionzip.com\\/","r11":"http:\\/\\/www.overstock.com\\/","r12":"http:\\/\\/www.bidspotter.com\\/","r13":"http:\\/\\/www.paypal.com\\/","r14":"http:\\/\\/www.ha.com\\/","r15":"http:\\/\\/www.onlineauction.com\\/","r16":"http:\\/\\/bidz.com\\/","r17":"http:\\/\\/www.epier.com\\/","r18":"http:\\/\\/www.sell.com\\/","r19":"http:\\/\\/www.rasmus.com\\/"}' 

ma ottenere che la stessa stringa, con un b davanti:

b'{"num":20,"status":"ok","r0":"http:\\/\\/www.propertyroom.com\\/","r1":"http:\\/\\/www.ubid.com\\/","r2":"http:\\/\\/www.bidcactus.com\\/","r3":"http:\\/\\/www.etsy.com\\/","r4":"http:\\/\\/us.ebid.net\\/","r5":"http:\\/\\/www.bidrivals.com\\/","r6":"http:\\/\\/www.ioffer.com\\/","r7":"http:\\/\\/www.shopgoodwill.com\\/","r8":"http:\\/\\/www.beezid.com\\/","r9":"http:\\/\\/www.webidz.com\\/","r10":"http:\\/\\/www.auctionzip.com\\/","r11":"http:\\/\\/www.overstock.com\\/","r12":"http:\\/\\/www.bidspotter.com\\/","r13":"http:\\/\\/www.paypal.com\\/","r14":"http:\\/\\/www.ha.com\\/","r15":"http:\\/\\/www.onlineauction.com\\/","r16":"http:\\/\\/bidz.com\\/","r17":"http:\\/\\/www.epier.com\\/","r18":"http:\\/\\/www.sell.com\\/","r19":"http:\\/\\/www.rasmus.com\\/"}' 

Successivamente, quando si tenta di eseguire

json.loads(urlopen('http://similarsitesearch.com/api/similar/ebay.com').read()) 

mi dà l'errore di messa ge:

TypeError: can't use a string pattern on a bytes-like object"

che sto assumendo ha qualcosa a che fare con il b?

ho importato urlopen da urllib.request, e io sono in esecuzione Python 3.

Tutte le idee?

risposta

0

urllib restituisce un array di byte, che presumo sia il valore predefinito in py3 e json è in attesa di una stringa. Provare avvolgendo il valore di ritorno in una chiamata str() prima di richiamare la chiamata JSON

j = str(urlopen('http://similarsitesearch.com/api/similar/ebay.com').read()) 
json.loads(j) 
+1

Hmmmm, ora il suo dicendomi che –

+3

Questo perché 'str()' non converte un 'byte' in un' str' in 3.x. –

6

È necessario esaminare il set di caratteri specificato nella Content-Type intestazione e decodifica da che prima di passarlo a json.load*().

+0

Sembra essere UTF-8, non si verifica alcuna decodifica automatica? (C'era storicamente?) –

+4

Non c'è mai stato; 'urllib.urlopen(). read()' ha restituito anche un test in 2.x. È successo che "json" andava bene così. –

+0

Mi spiace, non sono abbastanza comprensivo. Ulteriori chiarimenti? :) –

0

Sembra un byte literal. Esamina come ottieni i dati con http o come l'API restituisce i dati nelle intestazioni.

29

Il contenuto di read() è di tipo byte quindi è necessario convertirlo in una stringa prima di provare a decodificarlo in un oggetto json.

Per convertire byte in una stringa, modificare il codice per: urlopen('http://similarsitesearch.com/api/similar/ebay.com').read().decode("utf-8")

7

Ha funzionato bene: "Nessun oggetto JSON potrebbe essere decodificato"

def myView(request): 
    encoding = request.read().decode("utf-8") 
    dic = json.loads(encoding) 
    print(dic)