2010-06-12 7 views
10

Uso la funzione urlopen di per tentare di ottenere un risultato JSON dall'API di StackOverflow.L'urlopen di Urllib si interrompe su alcuni siti (ad esempio StackApps api): restituisce risultati immondizia

Il codice che sto usando:

>>> import urllib2 
>>> conn = urllib2.urlopen("http://api.stackoverflow.com/0.8/users/") 
>>> conn.readline() 

Il risultato mi sto:

'\x1f\x8b\x08\x00\x00\x00\x00\x00\x04\x00\xed\xbd\x07`\x1cI\x96%&/m\xca{\x7fJ\... 

Sono abbastanza nuovo per urllib, ma questo non sembra come il risultato che dovrebbe essere sempre L'ho provato in altri posti e ottengo quello che mi aspetto (lo stesso che visitare l'indirizzo con un browser mi dà: un oggetto JSON).

L'utilizzo di urlopen su altri siti (ad esempio "http://google.com") funziona correttamente e mi dà l'html effettivo. Ho anche provato a usare urllib e dà lo stesso risultato.

Sono abbastanza bloccato, non sapendo nemmeno dove cercare di risolvere questo problema. Qualche idea?

+1

Grazie! Questo mi ha aiutato a eseguire il debug della mia app API :) – swanson

risposta

10

Che sembra quasi qualcosa da mangiare sottaceto. Forse qualcosa nella stringa User-Agent o nell'intestazione Accetta che urllib2 sta inviando sta causando a StackOverflow di inviare qualcosa di diverso da JSON.

Una spia è guardare conn.headers.headers per vedere cosa dice l'intestazione Content-Type.

E questa domanda, Odd String Format Result from API Call, potrebbe avere la risposta. In sostanza, potrebbe essere necessario eseguire i risultati attraverso un decompressore gzip.

doppio controllo con questo codice:

>>> req = urllib2.Request("http://api.stackoverflow.com/0.8/users/", 
          headers={'Accept-Encoding': 'gzip, identity'}) 
>>> conn = urllib2.urlopen(req) 
>>> val = conn.read() 
>>> conn.close() 
>>> val[0:25] 
'\x1f\x8b\x08\x00\x00\x00\x00\x00\x04\x00\xed\xbd\x07`\x1cI\x96%&/m\xca{\x7fJ' 

Sì, si sono sicuramente ricevendo dati gzip codificati indietro.

Poiché sembra che si ottengano risultati diversi su macchine diverse con la stessa versione di Python e in generale sembra che l'API urllib2 richieda di fare qualcosa di speciale per richiedere dati codificati gzip, suppongo che tu abbia un proxy trasparente lì da qualche parte.

Ho visto una presentazione EFF presso CodeCon nel 2009. Stavano eseguendo test di connettività end-to-end per scoprire trucchi ISP sporchi di vario tipo. Una delle cose che hanno scoperto durante questo test è che un numero sorprendente di router NAT di livello consumer aggiunge intestazioni HTTP casuali o proxy trasparente. Potresti avere qualche componente della tua rete che aggiunge o modifica l'intestazione Accept-Encoding per rendere la tua connessione più veloce.

+0

Hmm, questo ha senso. Qualche idea sul perché questo sarebbe diverso su diversi computer (eseguendo la stessa versione di Python)? –

+1

@ Edan Maor: non ne ho idea. Mi sembra strano. – Omnifarious

+0

Sì, ho appena controllato il mio sistema e questo è stato sicuramente il problema (ho usato la guida trovata su http://diveintopython.org/http_web_services/gzip_compression.html per provare e decomprimere). Ancora non ho idea del perché questo accada solo per me, visto che funziona bene per altri sviluppatori qui, e apparentemente funziona bene anche per l'autore del wrapper. –

Problemi correlati