1. 程式人生 > >Python高階——mini_web框架(實現web框架介面,資料庫連線)

Python高階——mini_web框架(實現web框架介面,資料庫連線)

mini_web框架

http伺服器

import socket
import multiprocessing
import re
import mini_frame


class Http:
    def __init__(self):
        # 初始化屬性
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True
) self.server_socket.bind(("", 8080)) self.server_socket.listen(128) def start(self): # 接收客戶端訊息 while True: client_socket, ip_port = self.server_socket.accept() p1 = multiprocessing.Process(target=self.recv_msg, args=(client_socket, ip_port)) p1.start() client_socket.close() @staticmethod
def recv_msg(client_socket, ip_port): print("[客戶端]:", ip_port, "連線") client_data = client_socket.recv(4096) # 符合http協議的請求資訊 client_data = client_data.decode() print(client_data) if client_data == '': print("客戶端關閉") return # 資料分析 獲取資料路徑
data_list = client_data.split("\r\n") name = data_list[0] # get /index.html http/1.1 # 通過正則獲取檔案的名字 result = re.match(r"[^/]+(/[^ ]*)", name) # 獲取檔名 file_name = result.group(1) # print(file_name) # 設定主頁 if file_name == "/": file_name = "/index.html" if not file_name.endswith(".py"): # ./static/index.html # 獲取路徑資訊 file_path = "./static" + file_name # 進行檢測看看有沒有這個檔案 try: f = open(file_path, "rb") except Exception: # 沒有這個檔案 傳送應答資訊 not found response_line = "HTTP/1.1 404 NOT FOUND\r\n" response_body = "%s 404 not found we will rock you.." % file_name response_data = response_line + "\r\n" + response_body client_socket.send(response_data.encode()) else: # 成功後返回的資訊 找到這個檔案了 file_content = f.read() # 關閉檔案 f.close() # 應答資料是檔案讀取出來的 二進位制格式 response_body = file_content # 4 組織傳送應答資訊 # 應答行 response_line = "HTTP/1.1 200 OK\r\n" response_headers = "Server:python02\r\n" # response_headers += "Content-Type: text/html; charset=utf-8\r\n" # 組成應答頭 注意要有空行 response_headr = response_line + response_headers + "\r\n" # 應答頭是需要編碼 client_socket.send(response_headr.encode()) # 應答體是二進位制的 不需要編碼 client_socket.send(response_body) finally: # 為了告訴瀏覽器我的資料傳送完畢了 client_socket.close() else: response_line = "HTTP/1.1 200 OK\r\n" response_headers = "Server:python02\r\n" # 通過介面呼叫動態資源 response_body = mini_frame.application(file_name) response_data = response_line + response_headers + '\r\n' + response_body client_socket.send(response_data.encode()) client_socket.close() if __name__ == '__main__': http = Http() http.start()

伺服器框架

from pymysql import *
import re
# 路由列表(一個存放路徑和對應函式的字典)
FUNC_URL_LIST = {}


# 路由裝飾器,新建函式時,將路徑和函式名新增到路由列表中
def route(data):
    def func_out(func):
        FUNC_URL_LIST[data] = func

        def func_in():
            func()
        return func_in
    return func_out


@route("/index.py")
def index():
    # 開啟對應資源
    with open("./templates/index.html", encoding='utf-8') as f:
        content = f.read()
        # 建立資料庫連線
        conn = connect(host='localhost', port=3306, database='stock_db', user='root', passwd='zsh123', charset='utf8')
        # 建立遊標物件
        cursor = conn.cursor()
        sql = "select * from info;"
        # 執行sql語句
        cursor.execute(sql)
        # 返回sql語句執行結果
        stock_data = cursor.fetchall()
        # 要替換的html文字
        html = ''
        # 模板文字
        template = """
        <tr>
        <td>%s</td>
        <td>%s</td>
        <td>%s</td>
        <td>%s</td>
        <td>%s</td>
        <td>%s</td>
        <td>%s</td>
        <td>%s</td>
        <td>
            <input type="button" value="新增" id="toAdd" name="toAdd" systemidvaule="000007">
        </td>
</tr>
        """
        # 遍歷sql執行結果中的資料
        for i in stock_data:
            # 將資料新增到模板中,並新增到html文字中
            html += template % (i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7])
        # 將響應體原html文本里的{%content%}替換為新html體
        content = re.sub(r"{%content%}", html, content)
        # 關閉遊標物件和連線
        cursor.close()
        conn.close()
        # 返回響應體
    return content


@route("/center.py")
def center():
    with open("./templates/center.html", encoding='utf-8') as f:
        content = f.read()
        conn = connect(host='localhost', port=3306, database='stock_db', user='root', passwd='zsh123', charset='utf8')
        cursor = conn.cursor()
        sql = "select * from info inner join focus on focus.id=2 order by info.code;"
        cursor.execute(sql)
        stock_data = cursor.fetchall()
        html = ''
        template = """
        <tr>
            <td>%s</td>
            <td>%s</td>
            <td>%s</td>
            <td>%s</td>
            <td>%s</td>
            <td>%s</td>
            <td>%s</td>
            <td>
                <a type="button" class="btn btn-default btn-xs" href="/update/000007.html"> <span class="glyphicon glyphicon-star" aria-hidden="true"></span> 修改 </a>
            </td>
            <td>
                <input type="button" value="刪除" id="toDel" name="toDel" systemidvaule="000007">
            </td>
        </tr>
        """
        for i in stock_data:
            html += template % (i[1], i[2], i[3], i[4], i[5], i[6], i[9])
        content = re.sub(r"{%content%}", html, content)
        cursor.close()
        conn.close()
    return content


def application(file_name):
    try:
        # 通過路由列表找到對應的函式,返回執行結果
        func = FUNC_URL_LIST[file_name]
        return func()
    except Exception as e:
        # 如果沒有找到或發生異常,丟擲異常
        print(e)
        return "404 not found!"