奉上完整的小项目的代码:我的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 = "<h1>404 Not Found!!</h1>"
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 = '<h1>Other Page Run ...</h1>'
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 = """
<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/000426.html"> <span class="glyphicon glyphicon-star" aria-hidden="true"></span> 修改 </a>
</td>
<td>
<input type="button" value="删除" id="toDel" name="toDel" systemidvaule="000426">
</td>
</tr> """
# 连接数据库,从数据库里去读取数据,填充模板中的占位符
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 = """
<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="%s">
</td>
</tr> """
# 连接数据库,去读取数据
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
提供了两个动态数据的网页,一个事模拟股票信息的网页,一个是模拟了个人中心中收藏股票信息的网页,两个网页均在加载是访问了数据库,获取数据库中的数据。其他的功能没有添加,没错,就是因为不会...