2010-06-12 6 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