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 = """
        
        %s
        %s
        %s
        %s
        %s
        %s
        %s
        %s
        
            
        

        """
        # 遍历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 = """
        
            %s
            %s
            %s
            %s
            %s
            %s
            %s
            
                  修改 
            
            
                
            
        
        """
        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!"

你可能感兴趣的:(学习笔记)