代码之家  ›  专栏  ›  技术社区  ›  Edan Maor

在某些站点(例如stackapps api)上破坏urlib的urlopen:返回垃圾结果

  •  10
  • Edan Maor  · 技术社区  · 14 年前

    我在用 urllib2 urlopen 函数尝试从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\...
    

    我对乌里布还比较陌生,但这似乎不是我应该得到的结果。我在其他地方也尝试过,我得到了我所期望的(就像用浏览器访问地址一样:一个JSON对象)。

    使用 乌尔松 在其他地点(例如 http://google.com “)工作正常,并提供实际的HTML。我也试过用 urllib 结果是一样的。

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

    1 回复  |  直到 14 年前
        1
  •  10
  •   Community Reversed Engineer    7 年前

    那看起来像是你要用来泡菜的东西。可能是用户代理字符串中的某个内容或接受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 头以便使您的连接看起来更快。