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

无法在HTML中调用Netlify部署的Python预测函数问题排查

问题排查:Netlify部署的Python函数与前端交互异常

我尝试在index.html中调用部署于Netlify的PredictedLocation.py预测函数,期望实现获取用户输入的预算、城市、房产类型、周期后,返回对应房产的预测价格并在地图标注位置的功能,但目前无法正常运行。以下是我的代码,请帮忙排查问题:

PredictedLocation.py代码

import pandas as pd
from sklearn.ensemble import RandomForestRegressor
import folium
import webbrowser
import tempfile


def filter_data(data, budget, city, property_type):
    filtered_data = data.loc[(data['city'] == city) & (data['property_type'] == property_type) & (data['price'] <= budget)]
    return filtered_data


def predict_price(filtered_data, period):
    features = ['beds', 'baths']
    X = filtered_data[features]
    y = filtered_data['price']

    model = RandomForestRegressor(n_estimators=100, random_state=42)
    model.fit(X, y)

    predicted_price = model.predict([[3, 2], [4, 3], [3, 2], [4, 3]])
    predicted_price_period = predicted_price[int(period)-1]

    return predicted_price_period


def predict_location(data, budget, city, property_type):
    filtered_data = filter_data(data, budget, city, property_type)

    # 获取周期输入
    period = input("Enter the period (in months): ")

    predicted_price_period = predict_price(filtered_data, period)

    # 以筛选后第一个房产为中心创建地图
    center_lat = filtered_data.iloc[0]['latitude']
    center_lon = filtered_data.iloc[0]['longitude']
    map_location = [center_lat, center_lon]
    m = folium.Map(location=map_location, zoom_start=15)

    # 为每个符合条件的房产添加标记
    for index, row in filtered_data.iterrows():
        price = row['price']
        lat = row['latitude']
        lon = row['longitude']
        tooltip = f"Price: {price} PKR"
        folium.Marker([lat, lon], tooltip=tooltip).add_to(m)
        # 添加预测位置标记
        predicted_lat = filtered_data.iloc[0]['latitude'] + 0.001
        predicted_lon = filtered_data.iloc[0]['longitude'] + 0.001
        predicted_tooltip = f"Predicted Price: {predicted_price_period:.2f} PKR"
        folium.Marker([predicted_lat, predicted_lon], tooltip=predicted_tooltip, icon=folium.Icon(color='green')).add_to(m)


    # 保存地图到临时HTML文件
    temp_file = tempfile.NamedTemporaryFile(suffix='.html', delete=False)
    temp_file.close()
    m.save(temp_file.name)

    # 打开地图并打印预测价格
    webbrowser.open('file://' + temp_file.name, new=2)
    print(f"The predicted price for a {property_type.lower()} in {city} with a period of {period} months is approximately {predicted_price_period:.2f} PKR.")


if __name__ == "__main__":
    data = pd.read_csv('zameen_data.csv')

    budget = int(input("Enter your budget (in PKR): "))
    while True:
        city = input("Enter the city (Karachi, Lahore, or Islamabad): ")
        if city in ["Karachi", "Lahore", "Islamabad"]:
            break
        print("Invalid input. Please enter a valid city.")

    while True:
        property_type = input("Enter the property type (Flat, House, Penthouse, Farm House, Lower Portion, Upper Portion, or Room): ")
        if property_type in ["Flat", "House", "Penthouse", "Farm House", "Lower Portion", "Upper Portion", "Room"]:
            break
        print("Invalid input. Please enter a valid property type.")

    predict_location(data, budget, city, property_type)

index.html代码

<!DOCTYPE html>
<html>
<head>
    <title>Predicted Location and Price</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <style>
        .container {
            width: 80%;
            margin: 0 auto;
        }
        h1 {
            text-align: center;
            margin: 20px 0;
        }
        label {
            display: block;
            margin-bottom: 10px;
            font-size: 18px;
        }
        input[type="number"], select {
            padding: 10px;
            font-size: 18px;
            border-radius: 5px;
            border: 1px solid #ccc;
            width: 100%;
            margin-bottom: 20px;
            box-sizing: border-box;
        }
        button[type="submit"] {
            background-color: #4CAF50;
            color: white;
            padding: 12px 20px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 18px;
        }
        button[type="submit"]:hover {
            background-color: #45a049;
        }
        .result {
            margin-top: 30px;
            font-size: 18px;
            font-weight: bold;
            text-align: center;
        }
        .map-container {
            height: 500px;
            width: 100%;
            margin-top: 20px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Predicted Location and Price</h1>
        <form action="/" method="POST"> 
            {% csrf_token %} 
            <label for="budget">Budget (PKR):</label>
            <input type="number" id="budget" name="budget" required><br>
            <label for="city">City:</label>
            <select id="city" name="city">
                <option value="Karachi">Karachi</option>
                <option value="Lahore">Lahore</option>
                <option value="Islamabad">Islamabad</option>
            </select><br>
            <label for="property_type">Property Type:</label>
            <select id="property_type" name="property_type">
                <option value="Flat">Flat</option>
                <option value="House">House</option>
                <option value="Penthouse">Penthouse</option>
                <option value="Farm House">Farm House</option>
                <option value="Lower Portion">Lower Portion</option>
                <option value="Upper Portion">Upper Portion</option>
                <option value="Room">Room</option>
            </select><br>
            <label for="period">Period (in months):</label>
            <input type="number" id="period" name="period" required><br>
            <button type="submit">Predict Location and Price</button>
        </form>
        <div id="result" class="result"></div>
        <div id="map" class="map-container"></div>
    </div>
    <script src="https://api.mapbox.com/mapbox-gl-js/v2.6.0/mapbox-gl.js"></script>
    <link href="https://api.mapbox.com/mapbox-gl-js/v2.6.0/mapbox-gl.css" rel="stylesheet" />
    <script>
        mapboxgl.accessToken = 'sk.eyJ1IjoibXVzYTc4OSIsImEiOiJjbGY1ZDBzbzgwdHF5M3dvY3F4dGx4a210In0.l-i8jiaS8LWPyXj1ocQiCg';
        var map = new mapboxgl.Map({
            container: 'map',
            style: 'mapbox://styles/mapbox/streets-v11',
            center: [-122.4194, 37.7749],
            zoom: 12
        });
    </script>
    </body>
    </html> 

问题原因排查

1. Netlify函数适配错误

原Python代码是本地交互式脚本,依赖input()获取命令行输入、webbrowser打开本地地图文件,完全不符合Netlify Functions的运行逻辑:

  • Netlify函数必须是HTTP请求处理器,需要接收前端传来的POST/GET请求参数,返回JSON格式的响应,不能用input()或操作本地文件。
  • 需要重构代码为符合Netlify要求的函数格式,比如使用Flask框架封装接口,从请求体中提取budget、city、property_type、period参数。

2. 部署依赖与资源缺失

  • 未声明Python依赖:Netlify部署时需要在项目根目录创建requirements.txt,列出pandas、scikit-learn、folium等依赖包,否则函数运行会提示模块找不到。
  • 数据文件未部署:zameen_data.csv需要包含在Netlify的部署目录中,否则函数读取文件会报错。

3. 前后端交互逻辑错误

  • 表单提交路径错误:Netlify函数的访问路径通常是/.netlify/functions/[函数文件名],但HTML表单的action设为"/",无法正确触发函数。
  • Django模板语法无效:HTML中的{% csrf_token %}是Django框架的模板标签,纯HTML文件无法解析,会直接显示在页面上,需要删除。
  • 地图逻辑脱节:前端用Mapbox初始化地图,但后端用folium生成本地地图文件,两者没有关联。正确逻辑是后端返回预测价格和标注点坐标,前端用Mapbox渲染这些数据。

4. 代码逻辑缺陷

  • 预测逻辑不合理:predict_price函数中固定用[[3,2],[4,3],[3,2],[4,3]]作为输入,根据period取索引,这和周期没有实际关联,需要重新设计预测特征与周期的映射关系。
  • 重复添加标记:predict_location函数的循环中,每次迭代都添加同一个预测位置标记,应该将该代码移到循环外部,避免重复创建。
  • 空数据未处理:如果filtered_data为空(没有符合条件的房产),filtered_data.iloc[0]会抛出索引越界错误,需要添加判断逻辑处理空数据场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 06:37:39