Flask对接Genius API歌词生成器KeyError及页面不显示问题排查
Flask歌词生成功能网页不显示歌词问题修复
问题复现
基于Genius API+Flask开发网页端马尔可夫链歌词生成功能时,先后遇到两个问题:
- 初始版本直接通过
request.form['search']读取表单参数,访问首页时触发400 Bad Request报错,报错信息为KeyError: 'search' - 将参数读取方式改为
request.form.get('search', None)后报错消失,但提交歌手名后网页端无歌词展示,仅PyCharm终端能正常输出生成的歌词。
初始后端报错版本代码:
from flask import Flask, render_template, request from lyrics import scrapeLyricText from markov import MarkovLyrics app = Flask(__name__) def generateArtistLyrics(name): songs = scrapeLyricText(name) m = MarkovLyrics() for song in songs: m.populateMarkovChain(song) return m.generateLyrics() @app.route('/', methods=['GET', 'POST']) def lyricsGenerator(): lyrics = "" if request.method == "POST": artist = request.form['search'] lyrics = generateArtistLyrics(artist) return render_template('home.html', lyrics=lyrics) if __name__ == '__main__': app.run(debug=True)
修改后无报错但不显示歌词的后端代码:
from flask import Flask, render_template, request from lyrics import scrapeLyricText from markov import MarkovLyrics app = Flask(__name__) def generateArtistLyrics(name): songs = scrapeLyricText(name) m = MarkovLyrics() for song in songs: m.populateMarkovChain(song) return m.generateLyrics() @app.route('/', methods=['GET', 'POST']) def lyricsGenerator(): lyrics = "" if request.method == "POST": artist = request.form.get('search', None) lyrics = generateArtistLyrics(artist) return render_template('home.html', lyrics=lyrics) if __name__ == '__main__': app.run(debug=True)
初始前端模板代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Lyrics Generator</title> </head> <body> <h1>Welcome to Lyrics Generator</h1> <p>Here, you can generate lyrics by the artist of your choice!</p> <form action="{{url_for('lyricsGenerator')}}" method='POST'> <input type="text" id="search" name="search" placeholder="Search for an artist..."> <input type="submit"> </form> <p>{{ lyrics }}</p> </body> </html>
问题根因
两个问题的触发原因分别是:
- 初始KeyError:GET请求访问首页时请求体不包含表单
search字段,直接用字典键取值会触发键不存在的错误。 - 修改后网页不显示歌词:
- 没有做空参数校验,当
search字段为空时,空值/None直接传入爬虫和歌词生成函数,逻辑异常 - 调试阶段在
scrapeLyricText或generateLyrics方法中用print()把歌词输出到终端,但没有正确将歌词字符串作为返回值return给视图函数,导致传入模板的lyrics变量为空 - Jinja2模板默认会将文本中的换行符
\n识别为普通空白字符,即使传入了正确的多行歌词,直接放在<p>标签中也会丢失换行格式,看起来和无内容类似。
- 没有做空参数校验,当
修复方案
- 补全后端参数校验
在POST逻辑中增加空值判断,只有拿到合法的歌手名参数时才执行爬取和生成逻辑,修正后的后端代码如下:from flask import Flask, render_template, request from lyrics import scrapeLyricText from markov import MarkovLyrics app = Flask(__name__) def generateArtistLyrics(name): songs = scrapeLyricText(name) # 增加爬取结果校验,避免空数据传入马尔可夫链 if not songs: return "未找到该歌手的相关歌词,请检查歌手名称是否正确" m = MarkovLyrics() for song in songs: m.populateMarkovChain(song) generated = m.generateLyrics() print(generated) # 保留终端打印用于调试 return generated @app.route('/', methods=['GET', 'POST']) def lyricsGenerator(): lyrics = "" if request.method == "POST": artist = request.form.get('search', '').strip() if artist: lyrics = generateArtistLyrics(artist) else: lyrics = "请输入有效的歌手名称" return render_template('home.html', lyrics=lyrics) if __name__ == '__main__': app.run(debug=True) - 调整前端模板渲染逻辑
增加基础样式保留歌词换行格式,避免Jinja2默认吞掉换行导致内容显示异常,修正后的模板代码如下:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Lyrics Generator</title> <style> .lyrics-box { white-space: pre-wrap; line-height: 1.8; margin-top: 20px; padding: 15px; border: 1px solid #eee; border-radius: 4px; min-height: 100px; } </style> </head> <body> <h1>Welcome to Lyrics Generator</h1> <p>Here, you can generate lyrics by the artist of your choice!</p> <form action="{{url_for('lyricsGenerator')}}" method='POST'> <input type="text" id="search" name="search" placeholder="Search for an artist..."> <input type="submit"> </form> <div class="lyrics-box">{{ lyrics }}</div> </body> </html> - 全链路返回值检查
确认lyrics.py中的scrapeLyricText函数、markov.py中的generateLyrics函数都存在正确的return返回值,不要只在函数内部打印结果而不返回,否则视图层拿不到生成的歌词内容,自然无法传给前端渲染。
内容的提问来源于stack exchange,提问作者If On
相关产品推荐
相关产品推荐

