【问题标题】:Why this error from urllib?为什么来自 urllib 的这个错误?
【发布时间】:2011-12-07 07:09:00
【问题描述】:

我在使用 urllib 时遇到一个奇怪的错误:

INFO     2011-12-07 07:02:45,101 main.py:884] urlhttp://maps.googleapis.com/maps/api/geocode/json?latlng=59.3333,18.05&sensor=false
WARNING  2011-12-07 07:02:45,103 urlfetch_stub.py:428] Stripped prohibited headers from URLFetch request: ['Host']
ERROR    2011-12-07 07:02:45,210 main.py:346] HTTPResponse instance has no attribute 'readline': 
Traceback (most recent call last):
  File "/media/Lexar/montao/lib/webapp2/webapp2.py", line 545, in dispatch
    return method(*args, **kwargs)
  File "/media/Lexar/montao/montaoproject/main.py", line 885, in get
    jsondata = json.load(urllib2.urlopen(url))
  File "/usr/lib/python2.7/urllib2.py", line 126, in urlopen
    return _opener.open(url, data, timeout)
  File "/usr/lib/python2.7/urllib2.py", line 391, in open
    response = self._open(req, data)
  File "/usr/lib/python2.7/urllib2.py", line 409, in _open
    '_open', req)
  File "/usr/lib/python2.7/urllib2.py", line 369, in _call_chain
    result = func(*args)
  File "/usr/lib/python2.7/urllib2.py", line 1185, in http_open
    return self.do_open(httplib.HTTPConnection, req)
  File "/usr/lib/python2.7/urllib2.py", line 1176, in do_open
    resp = addinfourl(fp, r.msg, req.get_full_url())
  File "/media/Lexar/montao/google/appengine/dist27/urllib.py", line 978, in __init__
    addbase.__init__(self, fp)
  File "/media/Lexar/montao/google/appengine/dist27/urllib.py", line 926, in __init__
    self.readline = self.fp.readline
AttributeError: HTTPResponse instance has no attribute 'readline'

以前工作的代码是

  url = 'http://maps.googleapis.com/maps/api/geocode/json' + \
    '?latlng={},{}&sensor=false'.format(entity.geopt.lat, entity.geopt.lon)
  logging.info('url%s' % url)
  jsondata = json.load(urllib2.urlopen(url))

你能告诉我这里有什么问题吗?我在某处读到响应对象没有“get”方法,那么它是如何工作的呢?我认为不同之处在于我从 SDK 1.6 升级到了 1.6.1 预发行版。正在运行的代码与生成错误消息的代码之间可能存在其他一些差异。

谢谢

更新

如答案中所述,以下使用 urlfetch 可以代替:

  url = 'http://maps.googleapis.com/maps/api/geocode/json' + \
    '?latlng={},{}&sensor=false'.format(entity.geopt.lat, entity.geopt.lon)
  logging.info('url%s' % url)

  from google.appengine.api import urlfetch
  result = urlfetch.fetch(url)
  jsondata = json.loads(result.content)

【问题讨论】:

    标签: python google-app-engine urllib2


    【解决方案1】:

    这似乎是 SDK 的一个错误。我能够复制完全相同的行为。你有什么理由使用urllib2 而不是urllib?

    使用 Python2.7 和 SDK 1.6.1,我测试了以下内容:

    import urllib  
    url = 'http://maps.googleapis.com/maps/api/geocode/json' + \
            '?latlng={},{}&sensor=false'.format(entity.geopt.lat, entity.geopt.lon)
    logging.info('url%s' % url)
    jsondata = json.load(urllib.urlopen(url))
    

    它按预期工作。

    如果我能确定导致文件读取错误的原因,我会跟进/提交错误。

    注意:我测试了 KJuly 建议的代码,但失败并出现同样的错误。似乎urllib2 不应该依赖urllib。进一步挖掘。

    编辑:由于urllib 和urllib2 只是urlfetch 的包装,我还可以提出以下建议:

    from google.appengine.api import urlfetch
    result = urlfetch.fetch(url)
    jsondata = json.loads(result.content)
    

    第二次编辑:在任何一种情况下,我们都使用本地版本的 (/usr/lib/python2.7/urllib2.py) urllib2,然后尝试与 GAE 特定版本的 urllib (google/appengine/dist27/urllib.py) 进行交互。

    【讨论】:

    • 这很有趣。我会尝试所有这些。感谢您的观察并花时间解决我的问题
    • 妈妈..这很奇怪。我得到了正确的结果,如下图所示。我的python版本是2.7.2。 :?是的,urlfetch 很酷!
    【解决方案2】:

    丢失Request() 方法?也许它会起作用。

    headers = { 'Content-Type' : 'application/json' } // Maybe 'application/xml'
    data = None
    req  = urllib2.Request(url, data, headers)    
    resp = urllib2.urlopen(req)         
    data = resp.read()
    jsondata = json.load(data)
    

    我在 python 控制台中尝试过:

    >>> import urllib2
    >>> headers = { 'Content-Type' : 'application/json' }
    >>> data = None
    >>> req = urllib2.Request( “http://maps.googleapis.com/maps/api/geocode/json?latlng=59.3333,18.05&sensor=false”,数据,标题)
    >>> response = urllib2.urlopen(req)
    >>> data = response.read()
    >>> data

    它会正确打印数据。这是我的结果:

    【讨论】:

    • 谢谢,但我在尝试此答案时仍然收到错误消息。我真的不明白为什么。
    • @Nicke 我已经编辑过了。关注req = urllib2.Request(url, data, headers)。 :p
    • 感谢@Kjuly 的帮助。编辑后我仍然收到相同的错误消息。这是本地dev_appserver。我可以尝试将它部署到生产中,我在最新版本中没有这个错误,看看实际差异是什么,如果差异真的是我认为的那样,即从 SDK 1.6 切换到预发布 1.6.1显得无关。再次感谢您在这里提供帮助。
    猜你喜欢
    • 2022-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-08
    • 1970-01-01
    • 2020-09-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多