首页/新闻资讯/正文详情

Python餐厅推荐系统源码解析:从爬虫到Flask可视化全流程

发布时间:2026/9/23 15:09:18 来源:云帆数科 栏目:资讯中心
Python餐厅推荐系统源码解析:从爬虫到Flask可视化全流程
简介这份资源是面向Python初学者与推荐系统入门者的餐厅菜品推荐系统完整项目包以Python为核心技术栈解决从数据采集到个性化推荐落地的全流程实践问题。压缩包共97个文件约5.76MB包含7个py脚本、6个html页面、18个js与16个css前端资源以及xlsx城市数据表、png/jpg界面截图和requirements.txt依赖清单覆盖爬虫、Web服务与前端展示各环节。项目结构清晰spider-main目录负责抓取大众点评、美团等平台数据main模块实现城市与区域检索templates下提供搜索、排行、词云等页面便于理解推荐系统的数据获取、预处理、特征工程与模型构建思路。目前已有139人学习下载适合希望掌握Python数据分析、协同过滤与Flask/Django部署的读者参考可据此快速搭建可运行的推荐服务原型并拓展为课程设计或毕业项目。1. 从一份能跑起来的餐厅推荐系统源码说起很多做 Python 入门项目的人卡在同一个地方爬虫、清洗、建模、Web 展示各写各的拼不成一条能演示的链路。这份「基于 Python 的餐厅菜品推荐系统」把整条链路塞进了一个 zipspider-main负责从大众点评、美团抓城市和门店数据main目录里放着搜索与区域校验脚本app.py用 Flask 把推荐结果渲染到templates下的页面static/assets和img里是 ECharts 图表和界面截图。它解决的不是「推荐算法有多先进」而是「一个能讲清楚数据从哪来、怎么进模型、怎么在网页上看到」的完整闭环。适合正在找 Python 课程设计、毕业设计参考或者想跑通爬虫到可视化全流程的人。下面按我实际拆包的顺序讲重点放在怎么复现、参数怎么调、哪里容易翻车。2. 拆开 spider-main城市列表、门店搜索与区域校验怎么串2.1 三个脚本的分工与调用顺序spider-main里不是一个大爬虫而是拆成了city_search.py、store_search.py、store_search_dianping.py、area_check.py四个脚本配合dianping_cities.xlsx和meituan_cities.xlsx两个城市清单。这个设计的好处是城市列表可以离线维护门店搜索按平台分开区域校验单独跑不会因为某个平台改版把整条链路拖死。常见做法是先用city_search.py把两个 Excel 里的城市名转成平台可识别的城市 ID 或拼音再交给store_search.py和store_search_dianping.py去搜门店最后用area_check.py校验抓到的门店地址是否落在目标区域内。我一般会按这个顺序跑# 1. 先确认城市清单能读进来 python spider-main/city_search.py # 2. 跑美团门店搜索示例具体参数看脚本里的 argparse python spider-main/store_search.py --city-file spider-main/meituan_cities.xlsx --output data/meituan_stores.csv # 3. 跑大众点评门店搜索 python spider-main/store_search_dianping.py --city-file spider-main/dianping_cities.xlsx --output data/dianping_stores.csv # 4. 区域校验过滤掉不在目标商圈的门店 python spider-main/area_check.py --input data/meituan_stores.csv --area 朝阳区逻辑说明city_search.py通常只做城市名到平台参数的映射不发起大量请求所以先跑它成本最低。store_search.py和store_search_dianping.py是真正发请求的输出 CSV 方便后续用 pandas 处理。area_check.py放在最后是因为它依赖前面产出的地址字段如果地址本身没抓全校验结果会大量误杀。参数说明--city-file指向城市清单换城市就改这个文件--output决定中间结果落盘位置建议单独建data/目录不要和源码混在一起--area是区域过滤关键词不同平台地址格式不一样大众点评常带「商圈」后缀美团可能只到区所以这个参数要按平台微调。2.2 城市清单 Excel 的字段与维护方式dianping_cities.xlsx和meituan_cities.xlsx是整个爬虫的入口配置。它们通常至少包含城市名、城市拼音或 ID、所属省份这几列。很多人拿到源码直接跑报「城市不存在」八成是 Excel 里的城市名和脚本里拼 URL 用的字段对不上。我一般会先读一遍表头import pandas as pd for f in [spider-main/dianping_cities.xlsx, spider-main/meituan_cities.xlsx]: df pd.read_excel(f) print(f, df.columns.tolist(), df.shape) print(df.head(3))逻辑说明先看列名和前三行确认脚本里引用的列比如city_name、city_id确实存在。如果列名是中文而脚本里写的是英文要么改脚本要么在读取时重命名。参数说明pd.read_excel默认读第一个 sheet如果城市分多个 sheet要加sheet_name参数。提示城市清单不要频繁改改完先跑city_search.py验证再跑门店搜索。直接改 Excel 后跑全量出错很难定位是配置问题还是网络问题。2.3 请求频率与输出字段的控制门店搜索脚本里通常会有time.sleep或请求间隔参数。这个参数不是摆设调太小会被平台限流调太大跑一个城市要很久。我的经验是先拿一个城市、一个关键词试跑看返回条数和耗时再决定全量跑多久。# 伪代码展示常见控制点 import time import requests def search_store(city_id, keyword, page): url fhttps://example.com/search?city{city_id}kw{keyword}page{page} headers {User-Agent: Mozilla/5.0 ...} resp requests.get(url, headersheaders, timeout10) time.sleep(1.5) # 请求间隔按平台容忍度调整 return resp.json()逻辑说明timeout防止单次请求卡死time.sleep控制频率。参数说明间隔从 1 秒到 3 秒都有人用但更稳的做法是随机化比如time.sleep(1 random.random())避免固定节奏被识别。输出字段方面门店搜索至少要有门店名、地址、评分、评论数、人均价格后面推荐和可视化都依赖这些列。3. 从原始门店数据到推荐结果清洗、特征与 Flask 接口3.1 用 pandas 做缺失值、异常值和字段标准化爬下来的门店数据常见问题是评分是「暂无评分」、人均价格带「¥」符号、地址里混着换行和空格。直接丢给模型会报类型错误。我一般先做一轮清洗import pandas as pd import numpy as np df pd.read_csv(data/meituan_stores.csv) # 评分转数值非数值置为 NaN df[rating] pd.to_numeric(df[rating], errorscoerce) # 人均价格去掉货币符号和「元」 df[avg_price] df[avg_price].astype(str).str.replace(r[¥元], , regexTrue) df[avg_price] pd.to_numeric(df[avg_price], errorscoerce) # 缺失值处理评分缺失用中位数补价格缺失用同类均值补 df[rating] df[rating].fillna(df[rating].median()) df[avg_price] df[avg_price].fillna(df.groupby(category)[avg_price].transform(mean)) # 地址去空白 df[address] df[address].astype(str).str.strip().str.replace(r\s, , regexTrue) df.to_csv(data/stores_clean.csv, indexFalse)逻辑说明errorscoerce把无法转换的值变成 NaN避免整列报错。价格用正则去掉符号后再转数值。缺失值按业务补评分用中位数价格按品类均值比全局均值合理。参数说明groupby(category)里的category要确认清洗后还存在如果品类字段也是脏的先做品类标准化再补价格。3.2 特征选择评分、价格、品类和评论数怎么用推荐系统不一定非得上协同过滤。这份源码的场景是餐厅菜品推荐用户量未必大常见做法是用基于内容的推荐把门店或菜品的品类、价格区间、评分、评论数做成特征算相似度后排序。from sklearn.preprocessing import MinMaxScaler from sklearn.metrics.pairwise import cosine_similarity features df[[rating, avg_price, review_count]].copy() features[review_count] np.log1p(features[review_count]) # 评论数长尾取对数 scaler MinMaxScaler() features_scaled scaler.fit_transform(features) sim_matrix cosine_similarity(features_scaled)逻辑说明MinMaxScaler把不同量纲的特征压到 0 到 1避免价格数值大就主导相似度。评论数取log1p是因为少数门店评论数极高不处理会拉偏。参数说明如果品类是类别型要先做 one-hot 再拼进特征矩阵cosine_similarity输出的是门店两两相似度取 Top-N 就是推荐候选。注意不要直接把门店 ID 当特征也不要用未来数据比如推荐之后才产生的评论训练否则离线指标好看上线就翻车。3.3 app.py 里的路由与模板渲染app.py是 Flask 入口templates下有index.html、search.html、rank.html、region.html、word.html、team.html。从文件名看首页、搜索、排行、区域、词云、团队页都有。推荐结果通常通过/search或/recommend路由返回模板里用 Jinja2 渲染。from flask import Flask, render_template, request import pandas as pd app Flask(__name__) df pd.read_csv(data/stores_clean.csv) app.route(/search) def search(): keyword request.args.get(kw, ) if keyword: result df[df[name].str.contains(keyword, naFalse)].head(20) else: result df.head(20) return render_template(search.html, storesresult.to_dict(records)) if __name__ __main__: app.run(debugTrue)逻辑说明request.args.get拿查询参数str.contains做简单匹配to_dict(records)把 DataFrame 转成模板能遍历的列表。参数说明debugTrue只适合本地调试部署要关掉head(20)限制返回条数避免页面卡顿。如果推荐逻辑在单独模块里这里应该调用推荐函数而不是直接过滤。3.4 ECharts 图表与静态资源路径static/assets和main/echarts.py说明可视化是用 ECharts 做的。常见做法是后端把数据转成 JSON前端在rank.html或region.html里初始化图表。// 在模板里注入数据后初始化 var chart echarts.init(document.getElementById(rankChart)); chart.setOption({ xAxis: { type: category, data: {{ names | tojson }} }, yAxis: { type: value }, series: [{ type: bar, data: {{ scores | tojson }} }] });逻辑说明tojson是 Jinja2 过滤器把 Python 列表安全转成 JS 数组。参数说明names和scores要长度一致否则图表错位。静态资源路径在 Flask 里默认是/static/如果页面图表空白先看浏览器控制台是不是 404。4. 环境配置与依赖安装requirements.txt 之外还要注意什么4.1 用虚拟环境隔离依赖requirements.txt里通常有 Flask、pandas、numpy、scikit-learn、requests、beautifulsoup4、openpyxl、lxml 这些。直接全局装容易和系统里的包冲突我一般先建虚拟环境python -m venv venv # Windows venv\Scripts\activate # macOS / Linux source venv/bin/activate pip install -r requirements.txt逻辑说明虚拟环境把项目依赖和系统 Python 隔开删掉 venv 目录就能清理。参数说明如果requirements.txt没锁版本装完最好pip freeze requirements-lock.txt下次复现更稳。4.2 常见依赖版本冲突与处理pandas 和 numpy 版本不匹配、scikit-learn 太新导致旧 API 报错是这类项目最常见的环境问题。如果pip install后跑app.py报ImportError或AttributeError先看报错里提到的包和版本。pip show pandas numpy scikit-learn逻辑说明确认实际安装版本。参数说明如果源码里用了sklearn.cross_validation这种旧路径新版本已经移除要改成sklearn.model_selection。不要盲目降级所有包先定位是哪个 API 变了。提示openpyxl是读 Excel 城市清单用的如果没装pd.read_excel会报缺少引擎。lxml是 BeautifulSoup 的解析器不装会退回内置解析器速度慢且容错差。4.3 启动 Flask 与端口调整python app.py # 或指定端口 flask --app app run --port 5001逻辑说明app.py里如果写了app.run()直接跑就行。参数说明5000 端口在 macOS 上可能被系统服务占用换 5001 或 8080。如果页面能打开但静态资源 404检查templates里引用路径是不是/static/assets/...以及static目录是否在项目根下。5. 避坑与排查爬虫、编码、模板和模型加载的翻车记录5.1 爬虫返回空数据或直接 403现象store_search.py跑完输出 CSV 是空的或者请求返回 403。原因平台对请求头、频率、IP 有校验默认 User-Agent 或固定间隔容易被拦。解决补全User-Agent、Referer请求间隔随机化先小批量试跑确认能拿到数据再放大。5.2 Excel 城市清单读取报编码或引擎错误现象pd.read_excel报FileNotFoundError或ImportError: Missing optional dependency openpyxl。原因路径不对或者没装 openpyxl。解决用绝对路径或确认工作目录pip install openpyxl。如果 Excel 是.xls老格式还要装xlrd。5.3 模板渲染中文乱码现象页面显示房间这类乱码。原因文件编码不是 UTF-8或者 Flask 响应头没指定。解决确保templates下 HTML 和app.py都是 UTF-8HTML 里加meta charsetUTF-8Python 文件头加# -*- coding: utf-8 -*-。5.4 推荐结果每次刷新都一样现象搜索或推荐页面返回的列表固定不变。原因推荐逻辑写成了静态排序没有引入用户输入或随机性。解决检查app.py里是否真的调用了相似度计算还是直接df.head(20)。如果是演示至少按评分或评论数排序并允许通过参数切换。5.5 模型文件或数据路径写死现象换台机器跑就报FileNotFoundError。原因源码里用了绝对路径比如C:\Users\xxx\data\stores.csv。解决改成相对路径或者用os.path.dirname(__file__)拼路径。我一般会在项目根建data/所有中间文件都放里面脚本里统一用相对路径。6. 进阶把推荐结果做成可解释的排序与验证跑通之后真正让这个项目拿得出手的是推荐结果能解释、能验证。我一般会加一个简单的排序打分函数把相似度、评分、评论数加权而不是只按单一指标排。def rank_stores(df, sim_scores, w_sim0.5, w_rating0.3, w_review0.2): df df.copy() df[sim] sim_scores df[review_log] np.log1p(df[review_count]) df[score] ( w_sim * df[sim] w_rating * (df[rating] / 5.0) w_review * (df[review_log] / df[review_log].max()) ) return df.sort_values(score, ascendingFalse)逻辑说明w_sim、w_rating、w_review三个权重控制推荐偏向。相似度高但评分低的店不会排太前评论数取对数避免一家独大。参数说明权重之和建议为 1方便解释如果业务更看重评分把w_rating调到 0.5 以上。验证时可以用留一法拿掉用户历史里的一家店看推荐列表里是否出现同类店。验证方式看什么指标适用场景留一法命中率用户历史较少评分排序对比平均评分提升冷启动人工抽查品类相关性演示前快速检查注意离线指标好不代表线上好尤其是爬来的数据本身有偏差。我一般会在rank.html里同时展示推荐理由比如「相似度 0.82 / 评分 4.6」方便演示时讲清楚。从那以后我每次拿到这类源码包都强制先跑通一条最小链路一个城市、一个关键词、一个页面确认数据能落盘、模板能渲染、图表能出来再扩全量。希望帮到你。本文还有配套的精品资源点击获取

相关推荐

3个高频坑点搞定狂暴飞车下载,面试必问不再挂
3个高频坑点搞定狂暴飞车下载,面试必问不再挂

3个高频坑点搞定狂暴飞车下载,面试必问不再挂 看了一堆教程还是不会写项目?别慌,这其实是90%新手的通病。 很多兄弟在准备 面试必问 的编程题时,卡在“狂暴飞车下载”这个看似简单实则暗藏玄机的场景里。… · 2026/9/23 15:09:18

JSP+Servlet+MySQL宠物管理系统:JavaWeb课设完整实现与避坑指南
JSP+Servlet+MySQL宠物管理系统:JavaWeb课设完整实现与避坑指南

简介:这是一个基于JSPServletMySQL搭建的宠物管理系统源码包,面向初学Java Web的开发者,以简单直观的宠物分类查询、添加、编辑与删除功能,完整呈现增删改查模块的落地方式。系统原先缺少编辑与删除能力,后续补充升级&… · 2026/9/23 15:09:18

Maxent生态位建模实战:从安装配置到响应曲线解读
Maxent生态位建模实战:从安装配置到响应曲线解读

简介:本资源是一份面向生态学初学者与科研人员的MaxEnt物种分布建模入门指南,聚焦最大熵算法原理与实操落地,解决物种地理分布预测建模中的环境变量配置、样本处理、模型训练与结果解读等核心问题,广泛适用于濒危物种保护、外来种… · 2026/9/23 15:09:10

崇州白塔湖项目源码解析:3步搞定环境配置卡死难题
崇州白塔湖项目源码解析:3步搞定环境配置卡死难题

崇州白塔湖项目源码解析:3步搞定环境配置卡死难题 配置环境就卡半天,是不是你也经历过这种抓狂时刻?打开终端,依赖包装了一堆,报错信息却像天书一样滚个不停。别急着删库重装,今天咱们不聊虚的,直接切入崇州白塔湖这个典型工程案例的 源码解析… · 2026/9/23 18:15:56

Rockchip YTPHY校准包解析:DDR PHY参数集成与U-Boot部署指南
Rockchip YTPHY校准包解析:DDR PHY参数集成与U-Boot部署指南

简介:本资源是面向嵌入式Linux驱动开发工程师与RK3568平台硬件适配人员的YT8521S千兆PHY芯片驱动补丁包,解决该型号PHY在Rockchip RK3568平台(内核4.4/4.19)上缺失原生支持、无法完成链路建立与环回测试等关键问题。压缩包共11个文… · 2026/9/23 18:15:43

天正cad官网选型避坑指南:5个致命坑点详解
天正cad官网选型避坑指南:5个致命坑点详解

天正cad官网选型避坑指南:5个致命坑点详解 面试被问原理答不上来,简历写了三年经验却连天正cad官网的版本差异都说不清?这行干了十年,见过太多人栽在工具选型的坑里。今天这篇避坑指南,专治各种“看似会用实则瞎用”的疑难杂症。… · 2026/9/23 18:15:37

生肖排位速查手册:10分钟搞定算法与实现
生肖排位速查手册:10分钟搞定算法与实现

生肖排位速查手册:10分钟搞定算法与实现 别翻那几页纸的官方文档了,真没人有耐心从头读到尾。想要搞懂生肖排位,直接看这份 速查手册… · 2026/9/23 18:15:31

上海专升本师资怎么判断?为什么“公办在职教授授课”是关键
上海专升本师资怎么判断?为什么“公办在职教授授课”是关键

一句话结论:看一家上海专升本机构的实力,先看老师是谁。上海临港产业大学(指尖专升本)作为校企服务部的学历提升品牌,与多所公办本科院校官方合作,授课老师几乎都是公办院校在职教授——这直接决定了考纲把… · 2026/9/23 18:15:31

电动汽车制动系统设计:从法规到再生制动与踏板感的关键技术解析
电动汽车制动系统设计:从法规到再生制动与踏板感的关键技术解析

简介:PDF文献《电动汽车制动系统的设计》面向新能源汽车、汽车工程相关专业的学生与技术人员,聚焦电动汽车行驶安全中的制动问题,以真空助力器为核心,完整介绍制动系统的分析、计算与设计流程。资源为单份PDF文档,共1个… · 2026/9/23 18:15:25

3招搞定手机怎么下载微信面试难题实战项目解析
3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧
Win7无线热点配置工具源码解析:解决API失效的3个实战技巧

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧 Win7无线热点配置工具在Win10/11上跑不动?不是你的问题,是版本升级后 API 全变了。很多老项目里的 netsh wlan… · 2026/9/23 0:00:36

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码