我希望能够使用烧瓶和请求从 lastfm api 搜索艺术家/乐队的字段。而且我在语法和/或逻辑上有问题,但我不知道如何纠正它们。
from flask import Flask
from flask import render_template
from flask import request
import requests
import json
app = Flask(__name__)
app.debug = True
@app.route('/')
@app.route('/vista', methods=['GET', 'POST'])
def homepage():
params = {
'api_key': '5c1016ab26ab5b2f6ad21c3d873785bc',
'format' : 'json',
'artist': request.args.get('artista')
}
r = requests.get(
'http://ws.audioscrobbler.com/2.0/?method=artist.gettopalbums',
params=params)
return render_template('vista.html',
albums=r.json()['topalbums']['album'])
if __name__ == "__main__":
app.run (host = '127.0.0.1', port = 5000, threaded=True)
<form action="/buscador.py">
Artista: <input type="search" name="artista"><br>
<input type="submit" value="buscar">
</form>
目前尚不清楚您的问题是什么,但您的代码中有几个错误:
api_key
字符串,所以开头和结尾的花括号是多余的。artist
在发送的参数中应该更好,而不是在 URL 中,因为如果艺术家姓名包含空格或非 ascii 字符怎么办?它必须被正确地重新编码为有效的 URL。requests
如果您将它传递给它,它会处理它params
,但如果您将它放在 URL 中并使用简单的连接,则不会。json.loads()
会中断。对于 JSON 格式的响应,您必须添加一个带有 valueparams
的字段。format
"json"
['topalbums']['album']
中是一个列表(它可以有 50 个元素!)。如果您只想获取第一个,则需要设置[0]
为选择它(然后获取它['name']
)。不清楚您的视图(模板)是否只需要一个专辑或它们的列表,但['topalbums']['album']['name']
无论如何它都会失败。假设模板需要一个专辑列表,并且它自己负责使用 y 循环
album.name
或类似方式访问标题。这将是烧瓶代码:注意。为了满足客户的请求,您让 Flask 发出另一个 Web 请求。此请求需要一段时间,在此期间您的客户将等待答复。但更糟糕的是,由于 Flask 是单线程和单线程的,整个服务器会一直阻塞,直到它
requests
返回结果,阻止它为更多的客户端提供服务。它可能适合测试,但对于生产,您应该部署 Flaskgunicorn
,例如,以支持并发(当客户端等待其响应时,服务器可以处理其他人)。更新
前面的代码在用于
request.args.get('artista')
从表单中检索要搜索的艺术家时,隐含地期望该艺术家作为 URL 的一部分来访问它(即,在这样的请求中访问它:GET /vista?artista=Coldplay
例如)。但是,默认的 HTML 表单发出请求
POST
并以特殊方式将表单参数编码为 POST 正文的一部分,而不是在 URL 中,因此上述代码将不起作用。解决这个问题的一个简单方法是告诉浏览器表单应该发出请求
GET
而不是 POST。所以:另一种可能性是保持 FORM 原样(因此它将使用 POST),并更改 Flask 部分以获取艺术家的姓名,如下所示:
第二次更新
由于用户希望使用相同的视图来显示 FORM 及其结果(我没有正确理解的数据),事实证明相同的路线可能会或可能不会携带参数
artista
,这取决于它是否被称为仅仅是GET /
或响应提交的表格。需要在代码中区分这些情况,避免在没有
artista
搜索的情况下请求last.fm API。代码将是这样的:
FORM 必须对 route 执行 GET
/vista
,所以它应该是这样的: