(一)前言
最近在做自己的全棧項(xiàng)目的時(shí)候,免不了要自己做一個(gè)接口。作為一名菜鳥(niǎo)的后端碼農(nóng),剛開(kāi)始用的是MyEclipse 10 + Servlet來(lái)構(gòu)建自己的接口,雖然這個(gè)IDE已經(jīng)給我提供了極大的便利(原來(lái)的作法),但是當(dāng)我知道Flask的時(shí)候我就知道:我已經(jīng)回不去了。
(二)萬(wàn)年不變
1.簡(jiǎn)介
在Python浩如煙海的框架中,有兩款著名的Web框架,一個(gè)是Django,另一個(gè)就是Flask。正如Flask自身的介紹一樣:“A microframework”,相比較于Django它更加的輕量與靈活,更加適合于個(gè)人定制。類(lèi)似于接口之類(lèi)的比較迷你的需求,F(xiàn)lask更加適合,并且完全勝任。
2.安裝
安裝是最沒(méi)有意思的步驟了,網(wǎng)上教程一大堆,所以博主就不再贅述了。小伙伴們可以看這里。
(三)簡(jiǎn)單初識(shí)
現(xiàn)在,你的已經(jīng)安裝完Flask了,下面讓我們來(lái)初步使用一下它。
萬(wàn)物萬(wàn)事初始于“Hello world!”。
from flask import Flaskfrom
app = Flask(__name__)
@app.route('/')
def start():
return 'Hello world!'
if __name__ == '__main__':
app.run()
這就是一個(gè)最小的Flask程序,是不是簡(jiǎn)單到爆炸?route裝飾器直接指定了URL,后面的方法就是URL對(duì)應(yīng)的方法(這里是start方法),直接一個(gè)return就返回了響應(yīng)的內(nèi)容。就是這么簡(jiǎn)單,就是這么粗暴。
訪問(wèn)127.0.0.1:5000我們就可以看到響應(yīng)結(jié)果了
(四)構(gòu)建接口
1.目標(biāo)
在原來(lái)的服務(wù)端的功能中主要有三大功能:
- 根據(jù)頁(yè)碼和影片類(lèi)型參數(shù),響應(yīng)一個(gè)視頻列表JSON數(shù)據(jù);
- 根據(jù)頁(yè)碼,響應(yīng)一個(gè)新聞列表JSON數(shù)據(jù);
- 根據(jù)關(guān)鍵詞,響應(yīng)一個(gè)相應(yīng)的數(shù)據(jù)列表的JSON數(shù)據(jù);
由于其實(shí)這三個(gè)功能從實(shí)現(xiàn)邏輯上來(lái)講大同小異,所以本篇文章只以第一個(gè)功能作為例子進(jìn)行講解。
我們先來(lái)看一下數(shù)據(jù)庫(kù)中的數(shù)據(jù):

這里需要解釋一下的是leve1和leve2,leve1是視頻的一層分類(lèi),包括動(dòng)漫、紀(jì)錄片,學(xué)習(xí)等,而leve2則是在leve1之下的細(xì)分。
博主計(jì)劃的SC交互過(guò)程是這樣的:客戶(hù)機(jī)發(fā)送一個(gè)POST請(qǐng)求,請(qǐng)求中包含index,leve1和leve2,參數(shù)。如果leve2不為空,那么根據(jù)leve2和index來(lái)查詢(xún)數(shù)據(jù)庫(kù),然后根據(jù)固定的json返回格式返回給客戶(hù)端,就像這樣:

2.構(gòu)建
首先,我們需要獲取客戶(hù)機(jī)POST請(qǐng)求中的參數(shù),在Flask中我們可以輕松而又優(yōu)雅的獲取到:
index = request.args.get('index')
當(dāng)然我們也是需要考慮一個(gè)情況,那就是如果客戶(hù)機(jī)沒(méi)有傳遞這個(gè)參數(shù)那怎么辦?Flask也已經(jīng)替我們考慮了這個(gè)情況,當(dāng)發(fā)生諸如此類(lèi)的情況時(shí),F(xiàn)lask會(huì)拋出一個(gè)KeyError的異常,我們只需要try...except處理,返回一個(gè)表達(dá)錯(cuò)誤的JSON就可以啦!
OK!在寫(xiě)SQL語(yǔ)句之前我們還需要一個(gè)步驟,由于APP需要分頁(yè)功能,所以我們還需要計(jì)算頁(yè)碼,在外部我們先定義一個(gè)單請(qǐng)求返回?cái)?shù)據(jù)數(shù)(一個(gè)請(qǐng)求返回多少條數(shù)據(jù)):
pageCount = 20
現(xiàn)在讓我們來(lái)計(jì)算我們需要從哪一個(gè)數(shù)據(jù)開(kāi)始查詢(xún)數(shù)據(jù)庫(kù):
pageIndex = int(pageCount) * int(index)
注意:這里如果不進(jìn)行類(lèi)型的轉(zhuǎn)換的話(huà)會(huì)發(fā)生一個(gè)錯(cuò)誤,當(dāng)index=0的時(shí)候是沒(méi)有問(wèn)題的,pageIndex=0,但是當(dāng)index=1時(shí),pageIndex=111111111111,那就不對(duì)了。
現(xiàn)在我們來(lái)編寫(xiě)SQL語(yǔ)句,當(dāng)leve2是空字符串的時(shí)候:
sql = 'select title,url from FreeVideo where leve1="%s" limit %s,%s' % (leve1,pageIndex,pageCount)
當(dāng)leve2不是空字符串的時(shí)候:
sql = 'select title,url from FreeVideo where leve2="%s" limit %s,%s' % (leve2,pageIndex,pageCount)
接下來(lái)復(fù)用之前爬蟲(chóng)用的mysql類(lèi)來(lái)進(jìn)行數(shù)據(jù)庫(kù)的連接和查詢(xún)mysql的代碼:
db = mysql.Mysql()
db.queryData(sql=sql)
獲取結(jié)果集進(jìn)行遍歷,并且放入響應(yīng)結(jié)果數(shù)組中:
result = []
for item in result_mysql:
ji = {"title": item[0],"url":item[1]}
result.append(ji)
由于返回的JSON數(shù)據(jù)都包括三個(gè)字段:1.datas,這個(gè)字段包含返回的數(shù)據(jù)。2.msg:包含服務(wù)器返回的提示信息。3.success:包含操作結(jié)果成功還是失?。˙OOL類(lèi)型)。因此我定義了一下基礎(chǔ)返回響應(yīng)的函數(shù):
def getBaseReturnValue(data,msg,code):
json_data = json.dumps({'datas':data,'msg':msg,'success':code},ensure_ascii=False,encoding='gb2312')
return json_data
注意:由于返回的數(shù)據(jù)中包含中文的數(shù)據(jù),因此在運(yùn)用json模塊中的dumps方法時(shí)必須加上encoding參數(shù),否則服務(wù)器會(huì)報(bào)錯(cuò)!
終于,最后一步,根據(jù)響應(yīng)數(shù)據(jù)的長(zhǎng)度決定返回的數(shù)據(jù):
if len(result) == 0:
return getBaseReturnValue(data=result,msg="沒(méi)有更多數(shù)據(jù)!",code=False)
else:
return getBaseReturnValue(data=result,msg='OK',code=True)
(五)結(jié)語(yǔ)
我們來(lái)看一下最后的APP使用接口的效果:


最后的最后,github地址附上,所有的代碼都在這里!iCCUT-Server-Flask