Python之web框架


什么是web框架

框架,即framework,特指為解決一個開放性問題而設計的具有一定約束性的支撐結構,使用框架可以幫你快速開發特定的系統,簡單地說,就是你用別人搭建好的舞台來做表演。

對於所有的Web應用,本質上其實就是一個socket服務端,用戶的瀏覽器其實就是一個socket客戶端

最簡單的web框架

import socket

def handle_request(client):

    buf = client.recv(1024)
    client.send("HTTP/1.1 200 OK\r\n\r\n".encode("utf8"))
    client.send("<h1 style='color:red'>Hello, Python</h1>".encode("utf8"))

def main():

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('localhost',8001))
    sock.listen(5)

    while True:
        connection, address = sock.accept()
        handle_request(connection)
        connection.close()

if __name__ == '__main__':

    main()

最簡單的Web應用就是先把HTML用文件保存好,用一個現成的HTTP服務器軟件,接收用戶請求,從文件中讀取HTML,返回。

但是這些代碼太過繁瑣,因為我們不希望接觸到TCP連接、HTTP原始請求和響應格式,所以,需要一個統一的接口,讓我們專心用Python編寫Web業務。

 

這個接口就是WSGI(web網關接口協議):Web Server Gateway Interface。

利用WSGI搭建web框架

 

from wsgiref.simple_server import make_server


def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    return [b'<h1>Hello, web!</h1>']


httpd = make_server('', 8080, application)

print('Serving HTTP on port 8000...')
# 開始監聽HTTP請求:
httpd.serve_forever()

在平時的使用中,我們會在瀏覽器輸入地址中加入路徑相關信息,所以這里對原有框架進行升級。

在之前存儲着請求信息大字典的environ變量中,有一個"PATH_INFO"的鍵,可以獲取路徑相關信息。下面是關於原始服務器的升級:

from wsgiref.simple_server import make_server  # 使用這個庫之后,不需要對傳過來的請求進行解析,它自動幫我們進行處理


def application(environ, start_response):  # 一旦有客戶端連接時,自動執行
    # 瀏覽器傳過來的信息會被處理為一個大字典放入到environ中。
    start_response('200 OK', [('Content-Type', 'text/html')])  # 設置相應的請求頭
    # f1=open("index1.html","rb")
    # data1=f1.read()
    # f2=open("index2.html","rb")
    # data2=f2.read()
    path = environ['PATH_INFO']
    if path == "/111.html":
        return [b'<h1>Hello, web</h1>']
        # return [data1]
    elif path == "/222.html":
        return [b'<h1>Hello, Django</h1>']
        # return [data2]
    else:
        return ["<h1>404</h1>".encode('utf8')]
        # return [b'<h1>Hello, web!</h1>']            # 返回響應結果


httpd = make_server('', 8080, application)  # 這里需要傳入三個參數:ip地址,端口號,應用

print('Serving HTTP on port 8000...')
# 開始監聽HTTP請求:
httpd.serve_forever()
View Code

下一步

from wsgiref.simple_server import make_server  # 使用這個庫之后,不需要對傳過來的請求進行解析,它自動幫我們進行處理

def f1():
    f1=open("index1.html","rb")
    data1=f1.read()
    return [data1]

def f2():

    f2=open("index2.html","rb")
    data2=f2.read()
    return [data2]

def application(environ, start_response):  # 一旦有客戶端連接時,自動執行
    # 瀏覽器傳過來的信息會被處理為一個大字典放入到environ中。
    start_response('200 OK', [('Content-Type', 'text/html')])  # 設置相應的請求頭
    # f1=open("index1.html","rb")
    # data1=f1.read()
    # f2=open("index2.html","rb")
    # data2=f2.read()
    path = environ['PATH_INFO']
    if path == "/111.html":
        return f1()
        # return [b'<h1>Hello, web</h1>']
        # return [data1]
    elif path == "/222.html":
        return f2()
        # return [b'<h1>Hello, Django</h1>']
        # return [data2]
    else:
        return ["<h1>404</h1>".encode("utf-8")]
        # return [b'<h1>Hello, web!</h1>']            # 返回響應結果


httpd = make_server('', 8080, application)  # 這里需要傳入三個參數:ip地址,端口號,應用

print('Serving HTTP on port 8000...')
# 開始監聽HTTP請求:
httpd.serve_forever()
View Code

路由分發

from wsgiref.simple_server import make_server  # 使用這個庫之后,不需要對傳過來的請求進行解析,它自動幫我們進行處理

def r1():
    f1 = open("111.html", "rb")
    data1 = f1.read()
    return [data1]

def r2():
    f2 = open("222.html", "rb")
    data2 = f2.read()
    return [data2]

# 完成路由分發
def router():
    url_patterns = [
        ("/111.html", r1),
        ("/222.html", r2),
    ]
    return url_patterns

def application(environ, start_response):  # 一旦有客戶端連接時,自動執行
    # 瀏覽器傳過來的信息會被處理為一個大字典放入到environ中。
    start_response('200 OK', [('Content-Type', 'text/html')])  # 設置相應的請求頭
    path = environ['PATH_INFO']         # 獲取URL中的路徑

    url_patterns = router()
    func = None
    for i in url_patterns:
        if i[0] == path:
            func = i[1]
            return func()
    if func == None:
        return ['<h1> 404 </h1>'.encode("utf-8")]

httpd = make_server('', 8080, application)  # 這里需要傳入三個參數:ip地址,端口號,應用

print('Serving HTTP on port 8000...')
# 開始監聽HTTP請求:
httpd.serve_forever()
View Code

到現在,整個web框架就算完成了,接下來加入實時時間的功能,顯示在前端頁面

from wsgiref.simple_server import make_server  # 使用這個庫之后,不需要對傳過來的請求進行解析,它自動幫我們進行處理
import time

def f1(req):
    f1=open("index1.html","rb")
    data1=f1.read()
    return [data1]

def f2(req):
    print(req["QUERY_STRING"])      # 獲取表單中傳來的信息
    f2=open("index2.html","rb")
    data2=f2.read()
    return [data2]

def show_time(req):
    times = time.ctime()
    # return [b"<h1>time:%s</h1>" % times]        # 小問題,這種寫法是否正確?
    # return [("<h1>time:%s</h1>" % str(times)).encode("utf-8")]

    # 下面是純英文內容,如果有中文會出現亂碼
    # f = open("show_time.html", "r")
    # data = f.read()
    # data = data.replace("{{time}}", times)
    # return [data.encode("utf-8")]

    # 亂碼解決
    f = open("show_time.html", "rb")
    data = f.read()
    data = data.decode("utf-8")
    data = data.replace("{{time}}", times)
    return [data.encode("utf-8")]

def router():
    url_patterns = [
        ("/111.html", f1),
        ("/222.html", f2),
        ("/show_time", show_time)
    ]
    return url_patterns

def application(environ, start_response):  # 一旦有客戶端連接時,自動執行
    # 瀏覽器傳過來的信息會被處理為一個大字典放入到environ中。
    start_response('200 OK', [('Content-Type', 'text/html')])  # 設置相應的請求頭

    path = environ['PATH_INFO']
    url_patterns = router()
    for i in url_patterns:
        if i[0] == path:
            func = i[1]
            return func(environ)

    else:
        return ['<h1> 404 </h1>'.encode("utf-8")]


httpd = make_server('', 8080, application)  # 這里需要傳入三個參數:ip地址,端口號,應用

print('Serving HTTP on port 8000...')
# 開始監聽HTTP請求:
httpd.serve_forever()
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM