python学习之实现简单的miniWeb服务器

奉上完整的小项目的代码:我的miniWeb小项目

webServer部分:

#!/usr/bin/venv python3
# coding: utf-8

import socket
import multiprocessing
import re

import dynamic.WebFrame as WebFrame


class WebServer(object):
    def __init__(self):
        self.__tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.__tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
        self.__tcp_server_socket.bind(('', 7000))
        self.__tcp_server_socket.listen(128)

    def service_client(self, new_socket):
        request = new_socket.recv(4096).decode('utf-8')
        request_lines = request.splitlines()

        # for t in request_lines:
        #     print(t)

        file_name = ""
        ret = re.match(r"[^/]+(/[^ ]*)", request_lines[0])
        if ret:
            file_name = ret.group(1)
            print("FileName:" + file_name)
            if file_name == "/":
                file_name = "/index.html"

        if file_name.endswith(".html"):
            # 这里动态的处理
            env = {'PATH_INFO':file_name}
            # 调用框架中的application函数,进行通信
            response_body = WebFrame.application(env, self.__start_response)

            # 准备相应行
            response_line = "HTTP/1.1 %s\r\n" % self.__status
            # 准备响应头
            response_head = "Server: MiniWebServer3.0\r\n"

            # 拼接响应头数据
            for tmp in self.__params:
                response_head += "%s:%s\r\n" % tmp

            # 拼接响应报文
            response_data = response_line + response_head + "\r\n" + response_body
            # 发送报文
            new_socket.send(response_data.encode("utf-8"))
        else:
            try:
                with open("./static" + file_name, 'rb') as file:
                    file_data = file.read()
            except:
                # 如果没有找到
                response_line = "HTTP/1.1 404 NOT FOUND\r\n"
                response_head = "\r\n"
                response_body = "

404 Not Found!!

" response_data = response_line + response_head + response_body new_socket.send(response_data.encode("utf-8")) else: # 如果找到对应的文件读取并返回 response_line = "HTTP/1.1 200 OK\r\n" response_head = "\r\n" response = response_line + response_head new_socket.send(response.encode("utf-8")) response_body = file_data new_socket.send(response_body) # 关闭套接字 new_socket.close() def __start_response(self, status, params): """ 准备一个回调函数 :param status: 用来保存状态信息(字符串) :param params: 用来保存响应信息(列表包含元组表示键值关系) :return: """ self.__status = status self.__params = params def start(self): while True: new_socket, ip_port = self.__tcp_server_socket.accept() process = multiprocessing.Process(target=self.service_client, args=(new_socket, )) process.start() if __name__ == '__main__': server = WebServer() server.start()

WebFrame部分代码:

#!/usr/bin/venv python3
# coding: utf-8

import re
from pymysql import *

# 定义路由表
route_table = {}


def application(environ, start_response):
    """
    WSGI接口函数,实现服务器与框架的的通信,在框架中定义
    :param environ: 要被动态处理的(字典)
    :param start_response: 回调函数->用做与服务器程序的传值(函数)
    :return:
    """
    # 获取传入的字典
    file_name = environ['PATH_INFO']

    # 准备一个函数,来执行相应的操作
    function = other

    if file_name in route_table:
        function = route_table[file_name]

    # 执行function函数,返回相应体数据
    file_content = function()

    # 通过传入的函数,来实现回调
    start_response("200 OK", [("Content-Type",'Text/html;charsetutf-8')])
    # 讲body返回
    response_body = file_content
    return response_body


# 定义一个带参的装饰器,用来给路由表添加键值关系
def router(url):
    def set_fun(func):
        def wrapper(*args, **kwargs):
            return func(*args, **kwargs)
        # 给路由表添加关系
        route_table[url] = wrapper
        return wrapper
    return set_fun


def other():
    file_content = '

Other Page Run ...

' return file_content # ###############以下为web应用的动态处理函数############################## @router('/center.html') def center(): # 利用模板将个人中心页面展示出来 # 拼接模板路径 path = './templates/center.html' # 读取模板内容 with open(path, 'r') as f: file_content = f.read() # 准备数据 row_str = """ %s %s %s %s %s %s %s 修改 """ # 连接数据库,从数据库里去读取数据,填充模板中的占位符 conn = Connection(host='localhost',port=3306,database='stock',user='root',password="password",charset='utf8') cur = conn.cursor() sql_str = ''' select info.code,info.short,info.chg,info.turnover,info.price,info.highs,focus.note_info from info inner join focus on info.id = focus.info_id ''' cur.execute(sql_str) result = cur.fetchall() cur.close() conn.close() # 多整几条 all_data = '' for t in result: all_data += row_str % (t[0],t[1],t[2],t[3],t[4],t[5],t[6]) # 使用正则替换模板中的变量 file_content = re.sub(r'\{%content%\}', all_data, file_content) return file_content @router('/index.html') def index(): # 在这里,具体来处理相应返回的数据,并且将数据加到模板文件中,一起返回 # 拼接模板文件的路径 path = './templates/index.html' # 读取模板文件的内容 with open(path, 'r') as f: file_content = f.read() # 准备一条数据 row_str = """ %s %s %s %s %s %s %s %s """ # 连接数据库,去读取数据 conn = Connection(host='localhost',port=3306,database='stock',user='root',password='password',charset='utf8') cur = conn.cursor() sql_str = ''' select * from info; ''' cur.execute(sql_str) result = cur.fetchall() cur.close() conn.close() # 拼接几条数据 all_data = '' for t in result: all_data += row_str % (t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[1]) # '%s:%s' %('a','b) # 将拼接好的数据,替换到到模板中去,替换 {%content%} file_content = re.sub(r'\{%content%\}', all_data, file_content) return file_content

提供了两个动态数据的网页,一个事模拟股票信息的网页,一个是模拟了个人中心中收藏股票信息的网页,两个网页均在加载是访问了数据库,获取数据库中的数据。其他的功能没有添加,没错,就是因为不会...

你可能感兴趣的:(#,网络,python学习,python,webserver,miniweb,动态数据)