高天栋 王鹤颖 王葉萍 李时颖
摘 要:本文主要描述如何通过前端页面与数据库、后台的接口访问与逻辑实现搜索和相关功能。
关键词:433;搜索;开发
一、引言
“433”学生成长平台是服务于苏州经贸职业技术学院"433"学生成才工程的信息化平台。本文主要描述“433”学生成长平台中搜索功能及相关的开发与实现。
二、开发面临的主要问题
(一)网页采集数据杂乱
通过关键字获取数据时,毫无关系的网页、重复率极高信息使得获取到的数据格式杂乱无章,获取的规则极其不统一。使用xpath 模块可解决此问题,对指定网址采用指定采集方式,将数据统一存入指定格式的类再存入总数据库。
(二)用户输入关键词杂乱
用户使用搜索功能输入十分随意,如果输入英文单引号则会引起数据库存入数据报错。输入的关键词过长会引起长度溢出错误。使用replace()方法检测用户输入是否有英文单引号,如果存在则替换为中文单引号,当作字符串存入避免引发错误,而长度的问题初期使用了len()超过限制就删除超出的部分成功解决,目前是将数据库中varchar类型的列替换成了longtext类型,但随之而来的问题是longtext类型无法使用alter 从别的解码方式转换为utf8。我将数据库中原本的表删除,创建了一样的数据表并加上了charset = utf8;成功解决。
(三)服务器日志杂乱
开发时的环境在Windows下,在程序中写了很多捕获异常存入appLog.txt文本的脚本,方便后期查看报错。在centos7 linux 环境下部署完成项目使用时没有异常问题。上线一段时间后网站ip突然搜不到了,当我查看appLog.txt时发现,原本中文全部变成了乱码,而英文安然无恙,第一时间想到的就时写入时解码方式不正确,于是在with open 中加入了encoding=”utf8”的限制,重新部署一段时间后发现appLog.txt打开还是中文乱码。查询了csdn后了解到了windows系统下的txt默认为gbk编码,而linux默认是utf8编码,所以通过xftp传txt类型文件到linux时打开中文会乱码,于是使用了iconv -f gbk -utf8 appLog.txt > appLog.txt 解决了这个问题。
三、后端开发思路分析
(一)数据接口
前端界面与后端逻辑代码连接使用Flask中@app.route() 方法创建路由,使用render_template方法连接前端而实现,使用Falsk中request方法实现用户前端输入内容的获取,配合使用jianjia2模板引擎实现后端数据向前端返回指定格式数据,实现前后端数据互联互通又同时互不影响显示和使用。
(二)数据库
数据库使用mysql关系型数据库,使用pymysql模块连接。
(三)搜索逻辑
搜索主要使用了request需要获取用户网页前端输入的关键字,并将关键字进行规整化处理,从数据库中寻找是否相匹配的结果。如果用户输入关键字,返回的结果数量小10则从浏览器中再次搜索并将用户输入的关键字存入数据库,以便于线下扩充数据库。
其次就是对用户是否登录的检测,是否登录状态下对前端的不同返回,以及对程序异常的抓取,和程序日志的储存。以加强程序可维护性和稳定性。
@app.route("/",methods=["GET","POST"])def index():
if request.method == "GET":
try: id = session["id"] frequency = session["frequency"]
frequency = "重新查询!"%frequency
return render_template("index.html",userName=id,frequency=frequency,id=id)
except: return render_template("index.html",userName="请登录!")
elif request.method == "POST": userInput = request.form.get("userInput")
userInput = userInput.replace("'","‘")
# 提交用戶输入 库 sqlm = sql.Sql() question = sqlm.select(userInput)
try:sqlm = sql.Sql() sqlm.userInputSave(userInput)
except Exception as e:with open("appLog.txt","a",encoding="utf8") as f:
f.write( "\n" + str(e) + " \t " + time.strftime
('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))
if len(question) < 10: # 提交用户输入
quickm = quick.Quick(userInput=userInput)# 获取返回数据
question = quickm.main()
try:id = session["id"]
return render_template("q.html", id=id,question=question)
except:return render_template("q.html",id="请登录!",question=question)
(四)登录逻辑
登录功能使用了request和session完成了对用户账号密码的获取并对用户的账户进行了短时间的存储,同时使用存储后的账户从数据库中取出用户的网络ID。对用户的输入进行登录逻辑判断,为应对不同的情况使用了render_template方法对同一个界面做出了不同的返回。为减少代码的编写,使用request获取到用户的请求方式并做出不同响应。
@app.route("/login",methods=["GET","POST"])def login(): if request.method == "POST": userName = request.form.get("userName") # 获取用户用户名
password = request.form.get("password") # 获取用户密码 userSql = sql.Sql()
# 连接数据库# 将数据传入数据库 密码账户正确 返回 username,id,frequency 反之返回 Flase
data = userSql.userSelect(userName=userName, passWord=password)if data:
session["userName"] = data[1] session["id"] = data[0]
session["frequency"] = data[2] frequency = "请重新登录" % data[2]
return render_template("index.html",id=data[0],frequency=frequency)
else: return render_template("login.html",msg="密码或用户名错误")
elif request.method == "GET": return render_template("login.html")
(五)注册逻辑
注册功能也同样使用了request和session完成了对用户账号密码的获取并对用户的账户和用户自定义的网络ID进行了短时间的存储,同时也存入数据库供用户登录使用。对用户的输入进行注册逻辑判断,为应对不同的情况使用了render_template方法对同一个界面做出了不同的返回,和登录不同的是注册可能会出现账户相同的情况,使用了try…except的方法对异常经行捕捉并给用户返回对应提示。
@app.route("/zhuce",methods=["GET","POST"])def zhuce():
if request.method == "POST": userSql = sql.Sql()
userName = request.form.get("phone") passWord = request.form.get("password")
againPassword = request.form.get("againPassword") userId = request.form.get("id")
if passWord == againPassword and len(userId) <= 10: try: session["id"] = userId
session["userName"] = userName
userSql.userInsert(userName=userName, passWord=passWord, userId=userId)
return render_template("index.html",id=userId)
except: return render_template("zhuce.html",msg="你的手機号输入错误了!")
elif len(userId) > 10: return render_template("zhuce.html",msg="最多10个")
else: return render_template("zhuce.html",msg="两次密码不一样!")
elif request.method == "GET": return render_template("zhuce.html")
(六)留言板逻辑
留言板模块主要是为了收集评论和留言。重点技术使用了pymysql从数据库中拿到对应数据返回到前端使用jianjia2格式化排列输出,以做到网页动态显示,代码如下。
@app.route("/board",methods=["GET","POST"])def board():
if request.method == "GET": try:id = session["id"]
except: id = "请登录!"
boardSql=sql.Sql()data=boardSql.boardSelect()return ender_template("messageBoard.html",data=data,id=id)
elif request.method == "POST":
try: id = session["id"] userName = session["userName"]
except: id = "游客" userName = "游客"
boardSql = sql.Sql() text = request.form['text']
boardSql.boardInsert(text=text,userName=userName,who=id)
data = boardSql.boardSelect()
return render_template("messageBoard.html", data=data, id=id)
(七)公告逻辑
@app.route("/bulletinWall")def bulletinWall(): try: id = session["id"]
except: id = "请登录!"return render_template("bulletinWall.html",id=id)
参考文献:
[1] 杨选辉.信息系统分析与设计[J].北京:清华大学出版社.2016
[2] 钱雪忠.数据库原理及应用[M].北京:北京邮电大学出版社.2017.08
[3] 张海藩.软件工程导论[M].北京:清华大学出版社.2018