高天棟 王鶴穎 王葉萍 李時(shí)穎
摘 要:本文主要描述如何通過(guò)前端頁(yè)面與數(shù)據(jù)庫(kù)、后臺(tái)的接口訪問(wèn)與邏輯實(shí)現(xiàn)搜索和相關(guān)功能。
關(guān)鍵詞:433;搜索;開發(fā)
一、引言
“433”學(xué)生成長(zhǎng)平臺(tái)是服務(wù)于蘇州經(jīng)貿(mào)職業(yè)技術(shù)學(xué)院"433"學(xué)生成才工程的信息化平臺(tái)。本文主要描述“433”學(xué)生成長(zhǎng)平臺(tái)中搜索功能及相關(guān)的開發(fā)與實(shí)現(xiàn)。
二、開發(fā)面臨的主要問(wèn)題
(一)網(wǎng)頁(yè)采集數(shù)據(jù)雜亂
通過(guò)關(guān)鍵字獲取數(shù)據(jù)時(shí),毫無(wú)關(guān)系的網(wǎng)頁(yè)、重復(fù)率極高信息使得獲取到的數(shù)據(jù)格式雜亂無(wú)章,獲取的規(guī)則極其不統(tǒng)一。使用xpath 模塊可解決此問(wèn)題,對(duì)指定網(wǎng)址采用指定采集方式,將數(shù)據(jù)統(tǒng)一存入指定格式的類再存入總數(shù)據(jù)庫(kù)。
(二)用戶輸入關(guān)鍵詞雜亂
用戶使用搜索功能輸入十分隨意,如果輸入英文單引號(hào)則會(huì)引起數(shù)據(jù)庫(kù)存入數(shù)據(jù)報(bào)錯(cuò)。輸入的關(guān)鍵詞過(guò)長(zhǎng)會(huì)引起長(zhǎng)度溢出錯(cuò)誤。使用replace()方法檢測(cè)用戶輸入是否有英文單引號(hào),如果存在則替換為中文單引號(hào),當(dāng)作字符串存入避免引發(fā)錯(cuò)誤,而長(zhǎng)度的問(wèn)題初期使用了len()超過(guò)限制就刪除超出的部分成功解決,目前是將數(shù)據(jù)庫(kù)中varchar類型的列替換成了longtext類型,但隨之而來(lái)的問(wèn)題是longtext類型無(wú)法使用alter 從別的解碼方式轉(zhuǎn)換為utf8。我將數(shù)據(jù)庫(kù)中原本的表刪除,創(chuàng)建了一樣的數(shù)據(jù)表并加上了charset = utf8;成功解決。
(三)服務(wù)器日志雜亂
開發(fā)時(shí)的環(huán)境在Windows下,在程序中寫了很多捕獲異常存入appLog.txt文本的腳本,方便后期查看報(bào)錯(cuò)。在centos7 linux 環(huán)境下部署完成項(xiàng)目使用時(shí)沒(méi)有異常問(wèn)題。上線一段時(shí)間后網(wǎng)站ip突然搜不到了,當(dāng)我查看appLog.txt時(shí)發(fā)現(xiàn),原本中文全部變成了亂碼,而英文安然無(wú)恙,第一時(shí)間想到的就時(shí)寫入時(shí)解碼方式不正確,于是在with open 中加入了encoding=”utf8”的限制,重新部署一段時(shí)間后發(fā)現(xiàn)appLog.txt打開還是中文亂碼。查詢了csdn后了解到了windows系統(tǒng)下的txt默認(rèn)為gbk編碼,而linux默認(rèn)是utf8編碼,所以通過(guò)xftp傳txt類型文件到linux時(shí)打開中文會(huì)亂碼,于是使用了iconv -f gbk -utf8 appLog.txt > appLog.txt 解決了這個(gè)問(wèn)題。
三、后端開發(fā)思路分析
(一)數(shù)據(jù)接口
前端界面與后端邏輯代碼連接使用Flask中@app.route() 方法創(chuàng)建路由,使用render_template方法連接前端而實(shí)現(xiàn),使用Falsk中request方法實(shí)現(xiàn)用戶前端輸入內(nèi)容的獲取,配合使用jianjia2模板引擎實(shí)現(xiàn)后端數(shù)據(jù)向前端返回指定格式數(shù)據(jù),實(shí)現(xiàn)前后端數(shù)據(jù)互聯(lián)互通又同時(shí)互不影響顯示和使用。
(二)數(shù)據(jù)庫(kù)
數(shù)據(jù)庫(kù)使用mysql關(guān)系型數(shù)據(jù)庫(kù),使用pymysql模塊連接。
(三)搜索邏輯
搜索主要使用了request需要獲取用戶網(wǎng)頁(yè)前端輸入的關(guān)鍵字,并將關(guān)鍵字進(jìn)行規(guī)整化處理,從數(shù)據(jù)庫(kù)中尋找是否相匹配的結(jié)果。如果用戶輸入關(guān)鍵字,返回的結(jié)果數(shù)量小10則從瀏覽器中再次搜索并將用戶輸入的關(guān)鍵字存入數(shù)據(jù)庫(kù),以便于線下擴(kuò)充數(shù)據(jù)庫(kù)。
其次就是對(duì)用戶是否登錄的檢測(cè),是否登錄狀態(tài)下對(duì)前端的不同返回,以及對(duì)程序異常的抓取,和程序日志的儲(chǔ)存。以加強(qiáng)程序可維護(hù)性和穩(wěn)定性。
@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="請(qǐng)登錄!")
elif request.method == "POST": userInput = request.form.get("userInput")
userInput = userInput.replace("'","‘")
# 提交用戶輸入 庫(kù) 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)# 獲取返回?cái)?shù)據(jù)
question = quickm.main()
try:id = session["id"]
return render_template("q.html", id=id,question=question)
except:return render_template("q.html",id="請(qǐng)登錄!",question=question)
(四)登錄邏輯
登錄功能使用了request和session完成了對(duì)用戶賬號(hào)密碼的獲取并對(duì)用戶的賬戶進(jìn)行了短時(shí)間的存儲(chǔ),同時(shí)使用存儲(chǔ)后的賬戶從數(shù)據(jù)庫(kù)中取出用戶的網(wǎng)絡(luò)ID。對(duì)用戶的輸入進(jìn)行登錄邏輯判斷,為應(yīng)對(duì)不同的情況使用了render_template方法對(duì)同一個(gè)界面做出了不同的返回。為減少代碼的編寫,使用request獲取到用戶的請(qǐng)求方式并做出不同響應(yīng)。
@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()
# 連接數(shù)據(jù)庫(kù)# 將數(shù)據(jù)傳入數(shù)據(jù)庫(kù) 密碼賬戶正確 返回 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 = "請(qǐng)重新登錄" % data[2]
return render_template("index.html",id=data[0],frequency=frequency)
else:? return render_template("login.html",msg="密碼或用戶名錯(cuò)誤")
elif request.method == "GET": return render_template("login.html")
(五)注冊(cè)邏輯
注冊(cè)功能也同樣使用了request和session完成了對(duì)用戶賬號(hào)密碼的獲取并對(duì)用戶的賬戶和用戶自定義的網(wǎng)絡(luò)ID進(jìn)行了短時(shí)間的存儲(chǔ),同時(shí)也存入數(shù)據(jù)庫(kù)供用戶登錄使用。對(duì)用戶的輸入進(jìn)行注冊(cè)邏輯判斷,為應(yīng)對(duì)不同的情況使用了render_template方法對(duì)同一個(gè)界面做出了不同的返回,和登錄不同的是注冊(cè)可能會(huì)出現(xiàn)賬戶相同的情況,使用了try…except的方法對(duì)異常經(jīng)行捕捉并給用戶返回對(duì)應(yīng)提示。
@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="你的手機(jī)號(hào)輸入錯(cuò)誤了!")
elif len(userId) > 10: return render_template("zhuce.html",msg="最多10個(gè)")
else: return render_template("zhuce.html",msg="兩次密碼不一樣!")
elif request.method == "GET": return render_template("zhuce.html")
(六)留言板邏輯
留言板模塊主要是為了收集評(píng)論和留言。重點(diǎn)技術(shù)使用了pymysql從數(shù)據(jù)庫(kù)中拿到對(duì)應(yīng)數(shù)據(jù)返回到前端使用jianjia2格式化排列輸出,以做到網(wǎng)頁(yè)動(dòng)態(tài)顯示,代碼如下。
@app.route("/board",methods=["GET","POST"])def board():
if request.method == "GET": try:id = session["id"]
except: id = "請(qǐng)登錄!"
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 = "請(qǐng)登錄!"return render_template("bulletinWall.html",id=id)
參考文獻(xiàn):
[1] 楊選輝.信息系統(tǒng)分析與設(shè)計(jì)[J].北京:清華大學(xué)出版社.2016
[2] 錢雪忠.數(shù)據(jù)庫(kù)原理及應(yīng)用[M].北京:北京郵電大學(xué)出版社.2017.08
[3] 張海藩.軟件工程導(dǎo)論[M].北京:清華大學(xué)出版社.2018