Urlopen Breaking di Urllib su alcuni siti (ad esempio API StackApps): restituisce risultati della spazzatura

StackOverflow https://stackoverflow.com/questions/3028426

Domanda

sto usando urllib2'S urlopen funzione per cercare di ottenere un risultato JSON dall'API StackOverflow.

Il codice che sto usando:

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

Il risultato che sto ottenendo:

'\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 il risultato che dovrei ottenere. L'ho provato in altri posti e ottengo quello che mi aspetto (come visitare l'indirizzo con un browser mi dà: un oggetto JSON).

Usando urlopen su altri siti (ad es.http://google.com") Funziona bene e mi dà un vero HTML. Ho anche provato a usare urllib E dà lo stesso risultato.

Sono abbastanza bloccato, senza nemmeno sapere dove cercare per risolvere questo problema. Qualche idea?

È stato utile?

Soluzione

Sembra quasi qualcosa che faresti da mangiare al sottaceto. Forse qualcosa nella stringa dell'agente utente o accetta l'intestazione che Urllib2 sta inviando sta facendo inviare StackOverflow per inviare qualcosa di diverso da JSON.

Un rivelatore è guardare conn.headers.headers Per vedere cosa dice l'intestazione del tipo di contenuto.

E questa domanda, Formato stringa dispari risultato dalla chiamata API, potrebbe avere la tua risposta. Fondamentalmente, potrebbe essere necessario eseguire il tuo risultato attraverso un decompressore GZIP.

Doppia 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ì, stai sicuramente ricevendo i dati codificati GZIP.

Dal momento che sembri ottenere risultati diversi su macchine diverse con la stessa versione di Python, e in generale sembra che l'API URLLIB2 richiederebbe di fare qualcosa di speciale per richiedere dati codificati GZIP, la mia ipotesi è che tu abbia un proxy trasparente da qualche parte.

Ho visto una presentazione del FEP di Codecon nel 2009. Stavano eseguendo test di connettività end-to-end per scoprire trucchi sporchi ISP di vario genere. Una delle cose che hanno scoperto mentre facevano questo test è che un numero sorprendente di router Nat a livello di consumo aggiunge intestazioni HTTP casuali o fanno proxy trasparenti. Potresti avere qualche equipaggiamento sulla tua rete che aggiunge o modifica il Accept-Encoding Intestazione per rendere la tua connessione più veloce.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top