【问题标题】:Error while importing Flickr api using Python on Google App Engine在 Google App Engine 上使用 Python 导入 Flickr api 时出错
【发布时间】:2013-10-13 12:30:21
【问题描述】:

我正在尝试做一个非常简单的 Python 网络服务。它使用 Flickr API 创建一个“photo.search”并返回标题和照片的 url。

此网络服务将托管在 Google App Engine 上。

这是我现在真正拥有的:

import webapp2
from urllib import urlencode, urlopen
from xml.dom import minidom
from google.appengine.api import urlfetch

class MainPage(webapp2.RequestHandler):

  def get(self):
    self.response.headers['Content-Type'] = 'text/plain'

    data = _doget('flickr.photos.search', text='to_search', per_page='2')
    self.response.write('Ok')

  def _prepare_params(params):
    for (key, value) in params.items():
        if isinstance(value, list):
            params[key] = ','.join([item for item in value])
    return params

  def _doget(method, auth=False, **params):

    params = _prepare_params(params)
    url = 'http://flickr.com/services/rest/?api_key=%s&method=%s&%s%s'% \
          ('stackoverflow_key', method, urlencode(params),
                  _get_auth_url_suffix(method, auth, params))

    result = urlfetch.fetch(url)
    minidom.parse(result.content)
    return result

application = webapp2.WSGIApplication([
    ('/', MainPage),
], debug=True)

我是 Python 的初学者,所以如果我犯了很大的错误,我深表歉意 :) 我尝试了几个无效的教程和示例代码。

导入出现 500 服务器错误

Error: Server Error

The server encountered an error and could not complete your request.
If the problem persists, please report your problem and mention this error message and the query that caused it.

谁能告诉我它有什么问题?

如果有人有可以做到这一点的示例代码,那就太好了。

非常感谢您抽出宝贵时间!! :D

编辑:

好吧,我改了代码,比以前简单多了,用于测试:

import webapp2
from urllib import urlencode, urlopen
from xml.dom import minidom
from google.appengine.ext.webapp.util import run_wsgi_app
import hashlib
import os


HOST = 'http://api.flickr.com'
API = '/services/rest'
API_KEY = 'my_key'


class MainPage(webapp2.RequestHandler):

     def get(self):
        self.response.headers['Content-Type'] = 'text/html'

        data = _doget('flickr.photos.search', auth=False, text='to_search', per_page='1')
        if data:
           self.response.write(data)
        else:
            self.response.write('Error')

 def _doget(method, **params):

    url = '%s%s/?api_key=%s&method=%s&%s&format=json'% \
      (HOST, API, API_KEY, method, urlencode(params))

    res = urlfetch.fetch(url).content

    # Flickr JSON api returns not valid JSON, which wrapped with "jsonFlickrApi(...)", so we get rid of it.
    if 'jsonFlickrApi(' in res:
        return res[14:-1]

    return json.loads(res)

application = webapp2.WSGIApplication([
    ('/', MainPage),
], debug=True)

当我复制/粘贴此网址时,它可以完美运行。我的目标是在 flickr 返回数据时返回数据。但仍然无法正常工作。甚至没有显示打印:(

【问题讨论】:

    标签: python google-app-engine get flickr


    【解决方案1】:

    乍一看,您的应用有几个问题:

    1. 我想 HOST 应该是 'http://api.flickr.com'
    2. MainPage 类中 if-else 语句中的缩进和格式设置(:在 if 和 else 之后)
    3. self.response.write(photos) 中未定义的变量“照片”
    4. _doget 函数中未定义函数“_prepare_params”、“_get_auth_url_suffix”、“_get_data”和变量“debug”。
    5. 你应该调用urlopen结果的read()方法
    6. 您应该使用 minidom.parseString
    7. 您可以使用 run_wsgi_app 来运行您的应用程序

    下面是工作示例:

    from google.appengine.ext.webapp.util import run_wsgi_app
    import webapp2
    from urllib import urlencode, urlopen
    from xml.dom import minidom
    import hashlib
    import os
    
    HOST = 'http://api.flickr.com'
    API = '/services/rest'
    API_KEY = 'my_key'
    
    debug = False
    
    class MainPage(webapp2.RequestHandler):
    
        def get(self):
            self.response.headers['Content-Type'] = 'text/html'
    
            data = _doget('flickr.photos.search', auth=False, text='boston', per_page='2')
    
            if data:
                photos = data.getElementsByTagName("photo")
                for photo in photos:
                    farm_id = 1 # ???
                    server_id = photo.attributes['server'].value
                    photo_id = photo.attributes['id'].value
                    secret = photo.attributes['secret'].value
                    photo_url = 'http://farm{farm_id}.staticflickr.com/{server_id}/{photo_id}_{secret}.jpg'.format(farm_id=farm_id,                                                                                                         server_id=server_id,                                                                                                         photo_id=photo_id,                                                                                                         secret=secret)
                    self.response.write('<img src="{0}">'.format(photo_url))
            else:
                self.response.write('Error')
    
    
    def _doget(method, auth=False, **params):
        #print "***** do get %s" % method
    
        params = params
        url = '%s%s/?api_key=%s&method=%s&%s'% \
          (HOST, API, API_KEY, method, urlencode(params))
    
        #another useful debug print statement
        if debug:
            print "_doget", url
    
        res = urlopen(url)
        res = res.read()
    
        return minidom.parseString(res)
    
    
    application = webapp2.WSGIApplication([('/', MainPage),], debug=True)
    
    def main():
        run_wsgi_app(application)
    
    if __name__ == "__main__":
        main()
    

    格式化flickr照片的url我用http://www.flickr.com/services/api/misc.urls.html,但是我还没有找到farm_id参数在哪里,希望你自己管理)


    此外,通过将 'format=json' 传递给 API 请求 URL 可以更轻松地使用 json 格式,并且更正确地使用 GAE urlfetch 服务:

    import json
    from google.appengine.api import urlfetch
    
    # ...
    
    class MainPage(webapp2.RequestHandler):
        def get(self):
            # ...
            for photo in data['photos']['photo']:
                farm_id = 1 # ???
                server_id = photo['server']
                photo_id = photo['id']
                secret = photo['secret']
                # ...
    
    def _doget(method, auth=False, **params):
        # ...
        url = '%s%s/?api_key=%s&method=%s&%s&format=json'% \
          (HOST, API, API_KEY, method, urlencode(params))
    
        res = urlfetch.fetch(url).content
    
        # Flickr JSON api returns not valid JSON, which wrapped with "jsonFlickrApi(...)", so we get rid of it.
        if 'jsonFlickrApi(' in res:
            return res[14:-1]
    
        return json.loads(res)
    

    【讨论】:

    • 有没有办法调试它?因为我不够熟练,不知道我的错误在哪里=/
    • 嗯,首先你应该尽量小心,不要犯语法错误)你可以使用IDE语法错误突出或类似的工具。那么你在调试中最好的朋友应该成为 IDE 控制台、日志模块和“打印”。
    • 我只是更新我的帖子并粘贴我的“新代码”,调试起来更简单,但仍然无法正常工作,并且我的打印测试没有显示 =/
    • 请尝试我的示例,然后与您的示例进行比较。
    • 我试过了。我几乎有你所有的台词,除了 if data: self.response.write(data) else: self.response.write('Error')。看看我帖子的“编辑”部分,我得到了你的代码:(
    【解决方案2】:

    _get_data 是从哪里导入的?

    顺便说一句,appengine 附带一个 urlfetch 服务,除非你有充分的理由,否则我建议你使用它。见:https://developers.google.com/appengine/docs/python/urlfetch/

    在使用中,这看起来像:

    from google.appengine.api import urlfetch
    
    result = urlfetch.fetch(url=url)
    if result.status_code == 200:
        minidom.parse(result.content)
    

    【讨论】:

    • 好吧,我改了,谢谢 :) 你发现我的 _doget 函数有什么问题吗?因为当我调用它时,我的“Ok”语句不再显示
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-23
    • 2018-12-11
    • 2018-05-27
    相关资源
    最近更新 更多