Urlopen d'Urllib Breaking sur certains sites (par exemple, API StackApps): renvoie les résultats des ordures

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

Question

j'utilise urllib2's urlopen Fonction pour essayer d'obtenir un résultat JSON de l'API StackOverflow.

Le code que j'utilise:

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

Le résultat que je reçois:

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

Je suis assez nouveau pour Urllib, mais cela ne semble pas être le résultat que je devrais obtenir. Je l'ai essayé dans d'autres endroits et je comprends ce que j'attends (la même chose que visiter l'adresse avec un navigateur me donne: un objet JSON).

Utilisant urlopen sur d'autres sites (par exemple "http://google.com") fonctionne bien et me donne un véritable html. J'ai aussi essayé d'utiliser urllib Et cela donne le même résultat.

Je suis assez coincé, ne sachant même pas où chercher pour résoudre ce problème. Des idées?

Était-ce utile?

La solution

Cela ressemble presque à quelque chose que vous nourrissez à des cornichons. Peut-être que quelque chose dans la chaîne utilisateur-agent ou accepte l'en-tête que Urllib2 envoie fait que StackOverflow envoie autre chose que JSON.

Un révélateur est de regarder conn.headers.headers Pour voir ce que dit l'en-tête de type contenu.

Et cette question, Résultat du format de chaîne impair de l'appel de l'API, peut avoir votre réponse. Fondamentalement, vous devrez peut-être exécuter votre résultat via un décompresseur GZIP.

Double vérification avec ce code:

>>> 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'

Oui, vous obtenez certainement des données codées GZIP.

Puisque vous semblez obtenir des résultats différents sur différentes machines avec la même version de Python, et en général, il semble que l'API UrLlib2 vous obligeait à faire quelque chose de spécial pour demander des données codées GZIP, je suppose que vous avez un proxy transparent là-dedans là-dedans quelque part.

J'ai vu une présentation de l'EFF à Codecon en 2009. Ils effectuaient des tests de connectivité de bout en bout pour découvrir des astuces de FAI sales de divers types. L'une des choses qu'ils ont découvertes lors de ce test est qu'un nombre surprenant de routeurs NAT de niveau de consommation ajoutent des en-têtes HTTP aléatoires ou effectuent une proxyme transparent. Vous pourriez avoir un équipement sur votre réseau qui ajoute ou modifie le Accept-Encoding En-tête afin de rendre votre connexion plus rapide.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top