Urllib在某些网站上打破了urlopen(例如StackApps api):返回垃圾结果

时间:2010-06-12 10:58:16

标签: python urllib2 urllib urlopen

我正在使用urllib2的{​​{1}}函数尝试从StackOverflow api获取JSON结果。

我正在使用的代码:

urlopen

我得到的结果:

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

我对urllib相当新,但这似乎不是我应该得到的结果。我已经在其他地方尝试过了,我得到了我的期望(与使用浏览器访问地址一样:JSON对象)。

在其他网站上使用'\x1f\x8b\x08\x00\x00\x00\x00\x00\x04\x00\xed\xbd\x07`\x1cI\x96%&/m\xca{\x7fJ\... (例如“http://google.com”)可以正常工作,并为我提供实际的HTML。我也尝试过使用urlopen,它会得到相同的结果。

我很困惑,甚至不知道在哪里寻找解决这个问题。有什么想法吗?

1 个答案:

答案 0 :(得分:10)

这几乎看起来像是你要腌制的东西。也许urllib2正在发送的User-Agent字符串或Accepts标头中的某些内容导致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年看到了EFF在CodeCon上的演示。他们正在进行端到端的连接测试,以发现各种各样的脏ISP技巧。他们在进行此测试时发现的一件事是,令人惊讶的消费级NAT路由器添加随机HTTP标头或进行透明代理。您的网络上可能有一些设备正在添加或修改Accept-Encoding标头,以使您的连接速度更快。