You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask实现NBA数据答题:按钮交互与分数同步问题排查

NBA球员答题站答案校验同步问题解决方案

核心问题原因

  1. 每次请求(包括POST)都会先生成新题目,再处理用户答题请求,导致校验的是新题答案而非用户当前回答的题目
  2. 按钮未传递用户选择的选项,后端无法判断用户选的是哪个球员
  3. 全局score变量会被所有用户共享,多用户访问时分数会混乱

解决方案步骤

1. 后端代码修改(Python/Flask)

主要修改点:

  • 使用Flask session存储用户分数和当前题目的校验信息,避免全局变量冲突
  • 调整路由逻辑:POST请求时先校验用户答案,再生成新题目
  • 新增secret_key用于session加密

修改后的代码:

from flask import Flask, render_template, request, session
import random
from bs4 import BeautifulSoup
import requests

app = Flask(__name__)
app.secret_key = 'your-secret-key-here'  # 替换为任意随机字符串,用于session加密

# 爬取球员数据部分(保留原逻辑)
url = 'https://hashtagbasketball.com/fantasy-basketball-rankings'
data = requests.get(url).text
soup = BeautifulSoup(data, 'html.parser')
table = soup.find("table", attrs={"class": "table--statistics"})
table_data = table.find_all('tr')

players = []
for row in table_data[1:]:
    name = row.find_all('a')
    stat = row.find_all('span', id=True)
    for x in name:
        player = [
            x.text, stat[0].text, stat[1].text, stat[2].text,
            stat[3].text, stat[4].text, stat[5].text, stat[6].text,
            stat[7].text, stat[8].text
        ]
        players.append(player)

class Player:
    def __init__(self, player_data):
        self.name = player_data[0]
        self.field_goal_percentage = player_data[1]
        self.free_throw_percentage = player_data[2]
        self.three_points_made = player_data[3]
        self.points = player_data[4]
        self.rebounds = player_data[5]
        self.assist = player_data[6]
        self.steals = player_data[7]
        self.blocks = player_data[8]
        self.turnovers = player_data[9]

all_players = [Player(p) for p in players]

# 生成随机题目的函数
def generate_question():
    player1, player2 = random.sample(all_players, 2)
    categories = [
        'field_goal_percentage','free_throw_percentage','points','rebounds',
        'steals','assist','blocks','turnovers','three_points_made'
    ]
    category = random.choice(categories)
    category_text = category.replace('_',' ').capitalize()
    
    # 获取球员对应数据并转换为浮点型
    stat1 = float(getattr(player1, category))
    stat2 = float(getattr(player2, category))
    answer = 'a' if stat1 > stat2 else 'b'
    
    return {
        'player1_name': player1.name,
        'player1_stat': getattr(player1, category),
        'player2_name': player2.name,
        'player2_stat': getattr(player2, category),
        'category': category_text,
        'answer': answer
    }

@app.route("/", methods=['GET','POST'])
def quiz():
    # 初始化用户分数
    if 'score' not in session:
        session['score'] = 0
    
    if request.method == "POST":
        # 获取用户选择和当前题目的正确答案
        user_choice = request.form.get('choice')
        current_answer = session.get('current_answer')
        
        # 校验答案并更新分数
        if user_choice == current_answer:
            session['score'] += 1
        
        # 生成新题目
        new_question = generate_question()
        session['current_answer'] = new_question['answer']
        return render_template('home.html', **new_question, score=session['score'])
    
    # GET请求:生成第一题
    first_question = generate_question()
    session['current_answer'] = first_question['answer']
    return render_template('home.html', **first_question, score=session['score'])

if __name__ == '__main__':
    app.run(debug=True)

2. 前端代码修改(HTML)

主要修改点:

  • 给每个按钮添加明确的name和value,传递用户选择的a/b标识
  • 移除冗余的表单结构,确保后端能正确接收用户选择

修改后的代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>NBA Stats Quiz</title>
    <style>
        * { box-sizing: border-box; }
        .column { float: left; }
        .row:after { content: ""; display: table; clear: both; }
    </style>
</head>
<body>
    <h1 style="text-align:center;font-size:60px"> NBA Stats Quiz</h1>
    <h1 style="text-align:center;font-size:30px"> Which player's stat is higher?</h1>
    <h1 style="text-align:center;font-size:30px"> Category: {{category}}</h1>
    
    <div class="row">
        <!-- 左侧球员 -->
        <div class="column" style="text-align:center;width: 45%">
            <form method="post">
                <button style="font-size: 25px" type="submit" name="choice" value="a">
                    {{player1_name}}
                </button>
                <h2>{{player1_stat}}</h2>
            </form>
            <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a1/Ja_Morant_2021.jpg/800px-Ja_Morant_2021.jpg" style="height:300px">
        </div>
        
        <!-- 中间分数区域 -->
        <div class="column" style="text-align:center;width:10%">
            <h1>VS</h1>
            <h4>Current score</h4>
            <h4>{{score}}</h4>
        </div>
        
        <!-- 右侧球员 -->
        <div class="column" style="text-align:center;width:45%">
            <form method="post">
                <button style="font-size: 25px" type="submit" name="choice" value="b">
                    {{player2_name}}
                </button>
                <h2>{{player2_stat}}</h2>
            </form>
            <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a1/Ja_Morant_2021.jpg/800px-Ja_Morant_2021.jpg" style="height:300px">
        </div>
    </div>
</body>
</html>

关键修改说明

  1. Session存储:用session['score']替代全局变量,每个用户有独立分数;session['current_answer']存储当前题目的正确答案,确保校验时和用户看到的题目一致
  2. 路由逻辑调整:POST请求时先处理答题校验,再生成新题目,彻底解决校验新题答案的问题
  3. 前端表单优化:每个按钮提交对应的choice值,后端能准确获取用户选择

内容的提问来源于stack exchange,提问作者William

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 04:34:56