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

Flask人脸检测应用部署cPanel后提示“抱歉,出现错误”求助

Flask人脸检测应用cPanel部署报错排查方案

以下是针对你遇到的"We're sorry, but something went wrong"错误的具体排查方向和修复建议:

1. 相对路径导致的文件/目录访问失败

你的代码中大量使用../templates、../uploads这类相对路径,但cPanel+Passenger环境下,应用的工作目录可能并非你预期的python_files目录,导致无法找到模板、静态文件或无法写入上传目录。

修复方式:使用绝对路径替代相对路径
修改app.py:

import os
from flask import Flask, render_template, request, redirect
from werkzeug.utils import secure_filename
from prediction_blueprint import prediction_blueprint

# 计算项目根目录的绝对路径
base_dir = os.path.dirname(os.path.abspath(__file__))
# 确保uploads目录存在,不存在则创建
uploads_dir = os.path.join(base_dir, '../uploads')
os.makedirs(uploads_dir, exist_ok=True)

app = Flask(__name__, 
            template_folder=os.path.join(base_dir, '../templates'), 
            static_folder=os.path.join(base_dir, '../static'))
app.config['TEMPLATES_AUTO_RELOAD'] = True

app.register_blueprint(prediction_blueprint)


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


@app.route('/upload', methods=['POST'])
def upload():
    file = request.files['file']
    fn = secure_filename(file.filename)
    upload_path = os.path.join(uploads_dir, fn)
    try:
        file.save(upload_path)
        return {"success": True, "message": fn}
    except Exception as e:
        # 打印错误到日志,方便排查
        print(f"文件保存失败: {str(e)}")
        return {"success": False, "message": str(e)}, 500


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

同时修改prediction_blueprint.py中的extract_face函数路径:

# 替换原有的extract_face函数
def extract_face(image_name):
    # 从app模块导入uploads_dir,或者同样计算绝对路径
    from app import uploads_dir
    address = os.path.join(uploads_dir, image_name)
    
    img = cv.imread(address)
    if img is None:
        raise ValueError(f"无法读取图片: {address}")
    
    rgb_img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
    face_detections = detector_obj.detect_faces(rgb_img)
    if not face_detections:
        raise ValueError("未检测到人脸")
    
    face = face_detections[0]
    x, y, w, h = face['box']
    # 防止坐标越界
    x = max(0, x)
    y = max(0, y)
    w = min(img.shape[1] - x, w)
    h = min(img.shape[0] - y, h)
    
    actual_face = img[y:y + h, x:x + w]
    actual_face = cv.resize(actual_face, (224, 224))
    return np.asarray(actual_face)

2. 模型初始化失败(无日志捕获)

你的prediction_blueprint.py在模块级别直接加载VGGFace和MTCNN模型,这两个模型体积大、加载耗时,且如果加载失败会直接导致应用崩溃,但错误可能未被日志捕获。

修复方式:延迟加载模型并捕获初始化错误
修改prediction_blueprint.py:

from flask import Blueprint, request
from keras_vggface import VGGFace, utils
from keras_vggface.utils import preprocess_input
from mtcnn import MTCNN
import cv2 as cv
import numpy as np
import json, requests
import os

prediction_blueprint = Blueprint('prediction_blueprint', __name__)

# 初始化模型变量,延迟加载
vggface = None
detector_obj = None

@prediction_blueprint.before_app_first_request
def init_models():
    """在第一次请求前加载模型,捕获加载错误"""
    global vggface, detector_obj
    try:
        print("开始加载人脸检测模型...")
        detector_obj = MTCNN()
        print("MTCNN模型加载完成")
        
        print("开始加载VGGface模型...")
        vggface = VGGFace(model='vgg16')
        print("VGGface模型加载完成")
    except Exception as e:
        error_msg = f"模型加载失败: {str(e)}"
        print(error_msg)
        # 抛出错误让Passenger捕获
        raise RuntimeError(error_msg)

@prediction_blueprint.route('/predict', methods=['POST'])
def index():
    # 先检查模型是否加载成功
    if not vggface or not detector_obj:
        return {"success": False, "message": "模型未初始化完成"}, 500
    
    try:
        image = request.get_json().get('image')
        if not image:
            return {"success": False, "message": "未提供图片名称"}
        
        face = extract_face(image).astype('float32')
        input_sample = np.expand_dims(face, axis=0)
        samples = preprocess_input(input_sample)

        pred = vggface.predict(samples)
        output = utils.decode_predictions(pred)
        
        founded_person = output[0][0][0].replace("b'", "").replace("'", "")
        result = {"success": True, "message": {}}

        if founded_person:
            celeb_name = get_best_title_wiki_page(founded_person)
            if celeb_name:
                result['message']['celeb_name'] = celeb_name
                celeb_images = get_celeb_images(celeb_name)
                if celeb_images:
                    result['message']['celeb_images'] = celeb_images
                return result
            else:
                return {"success": False, "message": "未找到匹配的维基百科条目"}
        else:
            return {"success": False, "message": "未识别到任何人脸特征"}
    except Exception as e:
        error_msg = f"预测请求失败: {str(e)}"
        print(error_msg)
        return {"success": False, "message": error_msg}, 500

# 其他函数(extract_face、get_best_title_wiki_page、get_celeb_images)保持不变,注意路径已修改

3. Passenger WSGI文件优化(解决imp弃用警告)

虽然imp模块弃用警告不直接导致错误,但替换为标准的importlib可以避免潜在问题,同时确保WSGI文件配置正确:

修改passenger_wsgi.py:

import os
import sys
import importlib.util

# 将当前目录加入Python路径
sys.path.insert(0, os.path.dirname(__file__))

# 使用importlib加载app.py
spec = importlib.util.spec_from_file_location("wsgi", "app.py")
wsgi = importlib.util.module_from_spec(spec)
spec.loader.exec_module(wsgi)

# 导出Flask应用实例
application = wsgi.app

4. 权限问题排查

  • 确保uploads目录权限设置为755(cPanel下可通过文件管理器修改),且目录所属用户与cPanel运行用户一致。
  • 检查模板、静态文件目录的权限,确保Passenger进程有读取权限。

5. 开启详细日志

在app.py中添加日志配置,捕获更多错误信息:

import logging

# 配置日志文件,记录DEBUG级别以上的信息
logging.basicConfig(
    filename=os.path.join(base_dir, 'app.log'),
    level=logging.DEBUG,
    format='%(asctime)s - %(levelname)s - %(message)s'
)

部署后查看app.log文件,里面会包含详细的错误堆栈信息,帮助定位问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 05:47:05