10

我正在使用urllib2'surlopen函数尝试从 StackOverflow api 获取 JSON 结果。

我正在使用的代码:

>>> 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,它给出了相同的结果。

我很困惑,甚至不知道在哪里可以解决这个问题。有任何想法吗?

4

1 回答 1

10

这几乎看起来像你要喂泡菜的东西。也许 urllib2 发送的 User-Agent 字符串或 Accepts 标头中的某些内容导致 StackOverflow 发送 JSON 以外的内容。

一个迹象是查看conn.headers.headersContent-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标头,以使您的连接看起来更快。

于 2010-06-12T11:41:12.503 回答