2010-06-12 7 views
10

我正在使用urllib2urlopen函數嘗試從StackOverflow API獲取JSON結果。Urllib在某些站點上的urlopen突破(例如StackApps api):返回垃圾結果

我正在使用的代碼:

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

結果我得到:

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

我是相當新的urllib的,但是這似乎並不像結果我應該得到。我在其他地方嘗試了它,並得到了我期望的結果(與使用瀏覽器訪問地址給出的JSON對象相同)。

在其他網站上使用urlopen(例如「http://google.com」)工作正常,並給我實際的html。我也試過使用urllib,它給出了相同的結果。

我很堅持,甚至不知道在哪裏尋找解決這個問題。有任何想法嗎?

+1

謝謝!這幫助我調試我自己的API應用程序:) – swanson 2010-06-23 04:35:49

回答

10

這幾乎看起來像你會吃鹹菜。也許User-Agent字符串中的某些內容或urllib2發送的接受標頭會導致StackOverflow發送JSON以外的內容。

一個告誡是查看conn.headers.headers以查看Content-Type標頭說什麼。

而這個問題,Odd String Format Result from API Call,可能會有你的答案。基本上,你可能需要通過gzip解壓縮器運行你的結果。

雙重檢查與此代碼:

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

是的,你肯定是越來越gzip的編碼數據備份。

由於您似乎在具有相同版本的Python的不同計算機上獲得不同的結果,並且通常它看起來像urllib2 API會要求您做一些特殊的事情來請求gzip編碼的數據,我的猜測是您有一個透明代理在那裏。

2009年,我在CodeCon上看到了EFF的演示文稿。他們正在進行端到端的連接測試,以發現各種不好的ISP技巧。他們在進行此測試時發現的一件事是,令人驚訝的數量的消費級NAT路由器添加隨機HTTP標頭或進行透明代理。您的網絡中可能會有一些設備正在添加或修改Accept-Encoding標頭,以使您的連接看起來更快。

+0

嗯,這是有道理的。任何想法爲什麼這將在不同的計算機(運行相同版本的Python)不同? – 2010-06-12 12:11:38

+1

@Edan Maor:我不知道。我覺得很奇怪。 – Omnifarious 2010-06-12 12:16:17

+0

是的,我剛剛檢查了我自己的系統,這絕對是問題(我使用http://diveintopython.org/http_web_services/gzip_compression.html上的指南嘗試解壓縮)。 仍然不知道爲什麼這隻會發生在我身上,因爲它適用於其他開發人員在這裏,並且顯然對包裝的作者工作正常。 – 2010-06-12 12:23:52