2010-06-12 16 views
10

Używam funkcji urllib2urlopen, aby spróbować uzyskać wynik JSON z interfejsu API StackOverflow.Urodzinne łamanie Urlliba na niektórych stronach (na przykład StackApps api): zwraca wyniki śmieci

Kod używam:

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

Wynik Dostaję:

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

Jestem całkiem nowy, urllib, ale to nie wydaje się, że w wyniku powinien być coraz. Próbowałem go w innych miejscach i otrzymuję to, czego się spodziewam (tak samo, jak odwiedzanie adresu przy użyciu przeglądarki daje mi: obiekt JSON).

Korzystanie z urlopen na innych stronach (np. "http://google.com") działa dobrze i daje mi rzeczywisty HTML. Próbowałem również używać urllib i daje ten sam wynik.

Utknąłem, nie wiedząc nawet, gdzie szukać rozwiązania tego problemu. Jakieś pomysły?

+1

Dzięki! Pomogło mi to w debugowaniu mojej własnej aplikacji API :) – swanson

Odpowiedz

10

Wygląda to prawie jak coś, co można żerować. Może coś w ciągu znaków User-Agent lub Accepts, który wysyła urllib2, powoduje, że StackOverflow wysyła coś innego niż JSON.

Jedną z cech jest wyświetlenie conn.headers.headers, aby zobaczyć, co mówi nagłówek Content-Type.

To pytanie, Odd String Format Result from API Call, może zawierać odpowiedź. Zasadniczo, być może będziesz musiał uruchomić swój wynik przez dekompresor gzip.

podwójnej kontroli z tym kodem:

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

Tak, jesteś na pewno coraz gzip zakodowane dane z powrotem.

Ponieważ wydaje się, że uzyskujesz różne wyniki na różnych komputerach z tą samą wersją Pythona i ogólnie wygląda na to, że API urllib2 wymagałoby zrobienia czegoś specjalnego do zażądania zakodowanych danych gzip, domyślam się, że masz przezroczyste proxy tam gdzieś.

Widziałem prezentację EFF w CodeCon w 2009 roku. Przeprowadzali kompleksowe testy łączności, aby odkryć różne brudne sztuczki ISP. Jedną z rzeczy, które odkryli podczas testowania, jest to, że zaskakująca liczba routerów NAT na poziomie konsumenta dodaje losowe nagłówki HTTP lub przezroczyste proxy. Możesz mieć w sieci jakiś sprzęt, który dodaje lub modyfikuje nagłówek Accept-Encoding, aby twoje połączenie wydawało się szybsze.

+0

Hmm, to ma sens. Każdy pomysł, dlaczego byłoby inaczej na różnych komputerach (z tą samą wersją Pythona)? –

+1

@Edan Maor: Nie mam pojęcia. Wydaje mi się to dziwne. – Omnifarious

+0

Tak, właśnie sprawdziłem swój własny system i to był zdecydowanie problem (skorzystałem z przewodnika na http://diveintopython.org/http_web_services/gzip_compression.html, aby spróbować i rozpakować). Ciągle nie mam pojęcia, dlaczego tak się dzieje tylko dla mnie, ponieważ działa to dobrze dla innych programistów i najwyraźniej działa dobrze również dla autora opakowania. –