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

Flask假新闻检测应用预测按钮报错:服务器无法理解请求求助

Flask假新闻检测应用请求错误排查

开发假新闻检测Flask应用时,本地运行点击Submit按钮后出现错误:
The browser (or proxy) sent a request that this server could not understand.

以下是全部相关代码及问题分析:

Flask服务端代码

from flask import Flask, jsonify, request, render_template
from predictionModel import PredictionModel
import pandas as pd
from random import randrange

app = Flask(__name__, static_folder="./static",
            template_folder="./templates")

@app.route("/")
def home():
    return render_template('index.html')

@app.route('/predict', methods=['POST'])
def predict():
    data = request.json  
    model = PredictionModel(data)  
    result = model.predict()  
    return jsonify(result)

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

预测模型代码

import timeit
from nltk.stem import WordNetLemmatizer
from nltk import pos_tag
from nltk.corpus import stopwords
from nltk.corpus import wordnet
import pickle
import string
import nltk
nltk.data.path.append('./nltk_data')

start = timeit.default_timer()

with open("pipeline.pkl", 'rb') as f:
    pipeline = pickle.load(f)
    stop = timeit.default_timer()
    print('=> Pickle Loaded in: ', stop - start)

class PredictionModel:
    output = {}

    def __init__(self, text):
        self.output['original'] = text

    def predict(self):
        self.preprocess()
        self.pos_tag_words()

        clean_and_pos_tagged_text = self.output['preprocessed'] + \
            ' ' + self.output['pos_tagged']

        self.output['prediction'] = 'FAKE' if pipeline.predict(
            [clean_and_pos_tagged_text])[0] == 0 else 'REAL'

        return self.output

    def preprocess(self):
        text = self.output['original'].lower()

        text = [t for t in text.split(" ") if len(t) > 1]

        text = [word for word in text if not any(c.isdigit() for c in word)]

        text = [word.strip(string.punctuation) for word in text]

        stop = stopwords.words('english')
        text = [x for x in text if x not in stop]

        text = [t for t in text if len(t) > 0]

        pos_tags = pos_tag(text)

        text = [WordNetLemmatizer().lemmatize(t[0], self.get_wordnet_pos(t[1]))
                for t in pos_tags]

        self.output['preprocessed'] = " ".join(text)

    def get_wordnet_pos(self, pos_tag):
        if pos_tag.startswith('J'):
            return wordnet.ADJ
        elif pos_tag.startswith('V'):
            return wordnet.VERB
        elif pos_tag.startswith('N'):
            return wordnet.NOUN
        elif pos_tag.startswith('R'):
            return wordnet.ADV
        else:
            return wordnet.NOUN

    def pos_tag_words(self):
        pos_text = nltk.pos_tag(
            nltk.word_tokenize(self.output['preprocessed']))
        self.output['pos_tagged'] = " ".join(
            [pos + "-" + word for word, pos in pos_text])

HTML代码

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.3.1/dist/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

    <link href="https://unpkg.com/tailwindcss@2.2.15/dist/tailwind.min.css" rel="stylesheet">
    <title>Hello, world!</title>
  </head>
  <body>
    <header class="text-gray-600 body-font -my-10">
        <div class="container mx-auto flex flex-wrap p-5 flex-col md:flex-row items-center">
          <a class="flex title-font font-medium items-center text-gray-900 mb-4 md:mb-0">
            <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="w-10 h-10 text-white p-2 bg-purple-500 rounded-full" viewBox="0 0 24 24">
              <path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"></path>
            </svg>
            <span class="ml-3 text-xl">Fake News Detection</span>
          </a>
          <nav class="md:ml-auto flex flex-wrap items-center text-base justify-center">
            <a class="mr-5 hover:text-gray-900">Home</a>
            <a class="mr-5 hover:text-gray-900">Contact us</a>
            <a class="mr-5 hover:text-gray-900">About us</a>
            
          </nav>
          
        </div>
      </header><hr>
      <section class="text-gray-600 body-font">
        <div class="container px-5 py-24 mx-auto">
          <div class="flex flex-col text-center w-full mb-20">
            <h2 class="text-xs text-indigo-500 tracking-widest font-medium title-font mb-1">MACHINE LEARNING PROJECT</h2>
            <h1 class="sm:text-3xl text-2xl font-medium title-font mb-4 text-gray-900">Fake News Detection</h1>
            <p class="lg:w-2/3 mx-auto leading-relaxed text-base">It is an easy tool to detect whether your input news is real or fake.</p>
          </div>
        <div class="center">
            <form action="/predict" method="POST">
                <div class="form-group">
                  <label for="exampleInputEmail1">Enter News</label>
                  <input type="text" class="form-control" id="news" name="news"  aria-describedby="emailHelp" placeholder="Enter news">
                  <small id="emailHelp" class="form-text text-muted">Thankyou for using our product</small>
                </div>
                <button type="submit" class="btn btn-primary">Submit</button>
              </form>
        </div> 
          
          
        </div>
      </section>

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.14.7/dist/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.3.1/dist/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
  </body>
</html

问题核心原因

  • 请求格式不匹配:HTML表单默认以application/x-www-form-urlencoded格式发送数据,但Flask接口中用request.json尝试接收JSON格式数据,导致Flask无法解析请求,抛出错误。
  • 次要问题:HTML输入框为text类型,仅适合短文本,新闻内容通常较长,应改用textarea;HTML结尾标签未闭合(</html缺少>)。

修复方案

方案1:修改Flask接口接收表单数据(推荐)

将Flask的predict接口改为接收表单数据,适配原生表单提交:

@app.route('/predict', methods=['POST'])
def predict():
    # 接收表单中name为news的字段值
    data = request.form.get('news')
    if not data:
        return jsonify({'error': '请输入新闻内容'})
    model = PredictionModel(data)
    result = model.predict()
    # 若要返回页面展示结果,可改为render_template传递result参数
    return jsonify(result)

方案2:修改HTML用AJAX发送JSON数据

保留Flask的JSON接收逻辑,修改HTML表单用AJAX提交数据,避免页面刷新:

<!-- 替换原表单及脚本 -->
<form id="newsForm">
    <div class="form-group">
        <label for="news">Enter News</label>
        <textarea class="form-control" id="news" name="news" rows="5" placeholder="Enter news"></textarea>
        <small id="emailHelp" class="form-text text-muted">Thankyou for using our product</small>
    </div>
    <button type="submit" class="btn btn-primary">Submit</button>
</form>
<div id="result"></div>

<script>
$(document).ready(function() {
    $('#newsForm').submit(function(e) {
        e.preventDefault();
        const news = $('#news').val();
        $.ajax({
            url: '/predict',
            type: 'POST',
            contentType: 'application/json',
            data: JSON.stringify(news),
            success: function(res) {
                $('#result').html(`<p>原内容:${res.original}</p><p>检测结果:<strong>${res.prediction}</strong></p>`);
            },
            error: function(err) {
                alert('请求失败');
            }
        });
    });
});
</script>

额外修复

将HTML中的<input type="text">改为<textarea>,并闭合结尾的</html>标签为</html>。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 18:19:52