# Webapp_flask_lin **Repository Path**: nlby/webapp_flask_lin ## Basic Information - **Project Name**: Webapp_flask_lin - **Description**: 身临——一个使用Python Flask、MySQL数据库、JavaScript及爬虫的简单Web应用程序,提供智慧菜谱,心愿清单、热榜集合、用户管理系统的功能。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2021-02-03 - **Last Updated**: 2021-02-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 项目地址:[身临](http://jiel.yxinmiracle.com/) 本网站推荐**在电脑上使用谷歌浏览器**查看,所有功能需要登录查看,用户名密码不设要求,可随意设置,烦请看官老爷注册登录一下,[代码文档在master文件夹](https://gitee.com/ghislaine/webapp_flask_lin/tree/master/master)中,如遇到问题可随时与我联系。(vx:ljl_2333) ### **基本概述** 身临是一个专注于增进旅游体验的网站 ,基于bootstrap样式并使用云服务器部署。具有完善的MySQL数据库支持下的**用户系统**及**日志系统**,使用MD5信息摘要算法对用户的信息进行加密保护。在该网站,用户能够通过上传本地菜品的照片经过识别得到该**菜品**的信息,并由爬虫返回食材以及做法步骤;具备“汇总”、“待做”、“已做”三个分类的**心愿清单**提供记录想要在旅行中做的事情,让旅行不留遗憾,也可以用来记录旅行所需的物品,以便整理行囊;另外并且提供实时的GitHub/微博/v2ex/知乎/百度**热榜**的前五十条资讯,让用户随时随地掌握社会热点。随时校验用户登录状态,未登录不能功能,用户之间的信息不互通,保护隐私。 # 问题表述 ### **用户使用场景**(痛点): - 在大数据时代下,个人隐私的保护变得尤为重要,实名化的网站很容易让不法分子利用出卖用户信息获得巨大的商业利益。 - 有时看到一些美食的照片时垂涎欲滴,但是并不认识这是什么菜,也不知道怎么做。即使有一颗吃遍天下美食的心,也没有这样的时机,只能对着美食的照片默默啃馒头。 - 随着旅游普及率的提高,越来越多的人选择旅游作为休闲方式,但一大部分人们的旅游仅仅停留在打卡、拍照,表示自己到过了某个景点,但没有带着心愿出行的旅行总是少了那么一点色彩。而且没有记录的情况下,很容易导致旅行中忘记做某些事情,很容易让旅行留下遗憾。 - 在互联网走进每个角落的今天,各种资讯信息铺天盖地而来,如何在海量的信息中获取到对自己有价值的信息变得格外重要。 该项目的流程图:[可到process on查看](https://www.processon.com/view/link/600f8150079129045d37fa06) ![route](https://gitee.com/ghislaine/webapp_flask_lin/raw/master/pic/route.png) # 解决方案表述 ### **整体规划:** 用户管理系统、智能菜谱、心愿清单、热搜集合。 ### **用户痛点的解决:** - 本网站仅使用“用户名”及“密码”进行登录,通过数据库储存用户数据,使用MD5信息摘要算法对用户的信息进行加密保护,用户不需要提供真实姓名、邮箱等。用户名与密码不对应的情况下无法登录账号,无法使用功能。 - 用户可以通过上传本地图片,网站将基于百度ai开放平台的菜品识别人工智能API对菜品进行识别,再通过本网站自带的爬虫对菜肴食材以及制作方法进行汇总并展示。 - 用户在出行前可以使用心愿清单记录想要在旅行中做的事情,比如“品尝一次濑粉”、“在海边看一次日出”等,让旅行不留遗憾,也可以用来记录旅行所需的物品,以便整理行囊。该心愿清单具备“汇总”、“待做”、“已做”三个分类,各个事项一目了然,并且支持一键打卡、一键删除等功能。 - 本网站集合GitHub/微博/v2ex/知乎/百度热榜资讯,更方便用户浏览社会热点信息。 ### **使用到的python知识点:** | 知识点 | 使用场景 | | :-------: | :-----------------------------------------------------: | | 文件操作 | 用户上传图片到后端时利用文件路径生成识别路径对接API接口 | | 数据库 | 用户账号密码储存,登录时验证,日志系统数据储存 | | 环境配置 | 各种第三方库的调用 | | 函数/模块 | 将api、爬虫功能等封装成函数或者是模块以便调用 | | 等 | 等 | ### **未来迭代想法:** 结合[API期末项目](https://gitee.com/ghislaine/API/tree/main/文档说明)增加功能,进一步完善页面观感。 # 编程功能的基本描述 ### 项目架构 ``` │ README.md //项目文档 │ ├─master │ │ GetHot.py //热搜榜的爬虫 │ │ requirements.txt //第三方库安装 │ │ Server.py //运行 │ │ │ ├─App │ │ │ models.py //数据库的创建与管理 │ │ │ __init__.py │ │ └─__pycache__ │ │ │ ├─Config //配置数据库文件 │ │ │ config.py │ │ └─__pycache__ │ │ │ ├─settings //其他配置信息 │ │ │ settings.py │ │ │ │ │ └─__pycache__ │ │ │ ├─static //网站样式 │ │ ├─assets │ │ ├─bootstrap │ │ ├─css │ │ ├─js │ │ └─uploads │ │ │ ├─templates //静态文件模板 │ │ │ └─utils │ │ getDish.py //菜品识别API和菜谱爬虫 │ │ hashlib_md5_func.py //用户密码加密 │ └─__pycache__ │ └─pic //一些图片 ``` ### 具体实践思路 这里主要介绍使用数据库验证用户注册登录;判断用户登录状态;用户上传文件到后端。完整代码可到仓库查看。 - 用户注册/登录等(将用户注册所使用的用户名和密码存入建好的数据库,登录时用户通过提交form表单到后端进行判断是否存在该账号。如果注册成功会返回登录界面,注册失败会返回注册界面继续注册) ```python @app.route('/login', methods=["GET", "POST"]) def login(): """ 登录界面试图函数,如果用户成功登录那么就会注入session,方便后面进行判断用户有没有登录过 :return: 如果成功就返回index页面,如果没有成功就继续登录 """ if request.method == "GET": return render_template("sign_up.html") else: user_info = request.form.to_dict() username = user_info["username"] password = set_md5(user_info["password"]) flag = User.haveUser(username, password) if flag: session["username"] = username return redirect("/") else: return render_template("sign_up.html", tips="登录失败") @app.route('/reg', methods=["GET", "POST"]) def register(): """ 注册功能的视图函数,用户通过提交form表单到后端进行判断 用户的密码会使用MD5加密存储 :return: 如果注册成功会返回登录界面,注册失败会返回注册界面继续注册 """ if request.method == "GET": return render_template("sign_in.html") else: user_info = request.form.to_dict() username = user_info["username"] password = set_md5(user_info["password"]) # 密码通过MD5加密 flag = User.addUser(name=username, password=password) if flag == 0: print("用户注册成功") return render_template("sign_up.html") # 去登录 else: print("注册失败,原因有很多,我具体也不知道") return render_template("sign_in.html", tips="注册失败,请重新注册") ``` - 判断用户登录状态(校验用户请求这个网页之前有没有登录过,如果没有登录过就会跳转到登录界面) ```python """ 除了登录注册主页,其他页面都需要登录之后才能进行观看使用 """ # 校验session def warps(func): """ 装饰器,用来校验用户请求这个网页之前有没有登录过,如果没有登录过就会跳转到登录界面 :param func: :return: """ def inner(*args, **kwargs): if session.get("username"): ret = func(*args, **kwargs) return ret else: return redirect("/login") update_wrapper(inner, func) return inner ``` - 上传文件到页面并识别(保存用户上传图片的路径,对接百度API进行识别,得到菜品名后爬虫返回菜谱信息) ```python @app.route('/upload', methods=['POST', 'GET']) @warps def upload(): """ 用户上传照片进行分析的视图函数 :return: """ if request.method == 'POST': f = request.files['file'] print(f.filename) basepath = os.path.dirname(__file__) # 当前文件所在路径 upload_path = os.path.join(basepath, 'static//uploads', secure_filename(f.filename)) # 注意:没有的文件夹一定要先创建,不然会提示没有该路径 f.save(upload_path) dish_name = get_name(upload_path) title, zuofa_str, cailiao_str = getData(dish_name) # 在log数据库中添加 LogsDb.addLogs(username=session.get("username"), search_result=title, user_agent=request.user_agent, ip=request.remote_addr) return render_template('dish.html', title=title, zuofa_str=zuofa_str, cailiao_str=cailiao_str) else: return render_template("search_dish.html") ``` # 云端项目部署的基本描述 ## 部分网页 - 登录页面 ![sign_up](https://gitee.com/ghislaine/webapp_flask_lin/raw/master/pic/sign_up.png) ![sign_in](https://gitee.com/ghislaine/webapp_flask_lin/raw/master/pic/sign_in.png) - 首页:网站简介说明以及功能说明。![homepage1](https://gitee.com/ghislaine/webapp_flask_lin/raw/master/pic/homepage1.png) ![homepage2](https://gitee.com/ghislaine/webapp_flask_lin/raw/master/pic/homepage2.png) ![description1](https://gitee.com/ghislaine/webapp_flask_lin/raw/master/pic/description1.png) ![description1](https://gitee.com/ghislaine/webapp_flask_lin/raw/master/pic/description2.png)![description1](https://gitee.com/ghislaine/webapp_flask_lin/raw/master/pic/description3.png) - 心愿清单:可随时添加、删除心愿,具备“汇总”、“待做”、“已做”三个分类,支持一键完成或者一键清除已经完成的心愿。 ![todo](https://gitee.com/ghislaine/webapp_flask_lin/raw/master/pic/todo.png) - 菜谱搜索:上传一张菜肴的图片,返回识别结果和烹饪所需的食材、菜谱。 ![dish](https://gitee.com/ghislaine/webapp_flask_lin/raw/master/pic/dish1.png) ![todo](https://gitee.com/ghislaine/webapp_flask_lin/raw/master/pic/dish2.png) - 热榜集合:实时搜集来自GitHub/微博/v2ex/知乎/百度热榜的前五十条资讯信息及其链接,可根据平台选择想看的内容。 ![top](https://gitee.com/ghislaine/webapp_flask_lin/raw/master/pic/top.png) - 日志系统: ![viewlog](https://gitee.com/ghislaine/webapp_flask_lin/raw/master/pic/viewlog.png) ## 云服务器部署 本网站使用的是云服务器部署,采用的是python flask+uwsgi+nginx的方式配置。 #### uwsgi 由于在生产的环境中,flask自带的服务器没办法提供负载均衡等任务分发的工作,为了更高的效率以及用户体验,采用uwsgi去包裹住flask去执行任务分发,,uwsgi支持多线程,将服务分成多个微型服务。 ![image-20210126094730515](https://gitee.com/yxinmiracle/pic/raw/master/20210126094730.png) #### nginx nginx中可以使用负载均衡,能够将请求发送到不同的服务中,也能够反馈请求的错误,以及日志记录,flask在uwsgi的包装下,变成了多个微型服务,当我们处理请求的时候,可以用nginx来进行分发任务。 ![image-20210126095100131](https://gitee.com/yxinmiracle/pic/raw/master/20210126095100.png) ### 功能实现 #### python的安装 先到官网下载python源码类型的xz版本,将压缩包放入服务器中,解压压缩包 ``` tar -xf Python-3.8.3.tar.xz ``` ![image-20210126100217279](https://gitee.com/yxinmiracle/pic/raw/master/20210126100217.png) #### 准备编译 ```shell # 编译前可能需要安装一些依赖环境 yum install zlib2-devel openssl-devel yum install zlib-devel openssl-devel # 开始编译 ./configure --prefix=/opt/python38 ``` #### 安装 ```shell make && make install ``` ### mysql的安装 找到合适的合适的rpm包进行下载安装,本项目使用的MySQL5.7,找到压缩包后进行解压,然后yum安装 ![image-20210126100515207](https://gitee.com/yxinmiracle/pic/raw/master/20210126100515.png) ```shell yum install -y *.rpm ``` #### 编写配置文件 ```shell vim /etc/my.cnf ``` #### 启动 ``` systemctl start mysqld ``` ### nginx的安装 #### 下载 ```shell wget http://nginx.org/download/nginx-1.18.0.tar.gz ``` #### 编译 ```shell ./configure --help yum install gcc zlib2-devel pcre-devel openssl-devel ./configure --prefix=/opt/nginx --with-http_ssl_module --with-http_stub_status_module make && make install ``` #### 启动 ```shell nginx ps -ef|grep nginx # 查看启动起来了嘛 ss -tnlp # 查看端口 ``` 接下里创建python的虚拟环境,然后配置uwsgi的配置文件: ```ini [uwsgi] # http服务端口 http=:8080 # socket端口 socket=:9009 # 项目根目录 chdir=/opt/en # 启动文件 wsgi-file=/opt/en/Server.py # 启动文件名 module=Server # app的名字 callable=app # 进程数 processes=4 # 线程数 threads=2 # 日志文件 daemonize=/opt/log/log.txt ``` nginx配置文件: ```shell location / { include uwsgi_params; uwsgi_param UWSGI_PYHOME /opt/en/env; # python虚拟环境 uwsgi_pass 127.0.0.1:9009; # 转发端口 uwsgi_param UWSGI_CHDIR /opt/en; # 项目根目录 uwsgi_param UWSGI_SCRIPT Server:app; # 启动文件名以及里面的app名 } location /static{ # 静态文件转发 root /opt/en; } ``` 启动 ```shell uwsgi --ini /etc/uwsgi.ini ``` # 学习/实践心得总结及感谢 从开始到结束虽然只持续了两天,但对我来说像是度过了两年。最大的心得就是“拖延症不能有!!”接触python语言以来这是第一个略有雏形的项目,脑子里还有很多想要迭代的想法,奈何时间短促只能制作粗糙了一点,但也算是让我了解了开发一个项目的思路如何落地变成实践,以及如何处理此间遇到的各种困难,也让我认识到了我是多么粗心大意以及沉不住气的一个人,接下来的学习会抱着更积极的心态。 在此感谢许智超老师的教导,感谢小信对我的全方位支持,感谢开源社区及各大软件的帮助,也感谢为我评分的你。 - [百度AI开放平台](http://ai.baidu.com/?track=cp:ainsem|pf:pc|pp:tongyong-kaifangpingtai|pu:kaifangpingtai|ci:|kw:10003799) - [Mongodb数据库基础](https://blog.csdn.net/caiyongxin_001/article/details/104740804) - [flask部署上线](https://zhuanlan.zhihu.com/p/56046697) - [simple-webapp-flask](https://github.com/mmumshad/simple-webapp-flask) - [bootstrap](https://getbootstrap.com/) - [Flask实战项目教程](https://www.bilibili.com/video/BV1jx411R73z?from=search&seid=4396158331539989929) - [Flask-SQLAlchemy数据库](https://www.bilibili.com/video/BV19k4y1d7G7) - [快速入门后台写接口](https://www.bilibili.com/video/BV1v7411M7us) - [JavaScript模板](https://mavo.io/docs/primer) - [Flask-User](https://github.com/lingthio/Flask-User) - [flask数据库模型](https://blog.csdn.net/pdcfighting/article/details/109088767) - [flask+mysql](https://blog.csdn.net/xun527/article/details/79435421) - [Flask的设计思路](https://www.jianshu.com/p/a986b8ba057c?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation) - [CSS 教程](https://www.runoob.com/css/css-tutorial.html) - [人人都是产品经理](http://www.woshipm.com/) - [产品需求文档(PRD)的写作方法](http://www.woshipm.com/pd/80054.html) - [colordrop](https://www.colordrop.io/) - [ProcessOn](https://www.processon.com/) - [typora](https://www.typora.io/) - [MYSQL常用操作命令](https://www.cnblogs.com/shierlou-123/p/11207508.html)