1. 了解服务器与浏览器之间的简单传输
(1)服务器接收到数据会发送给我们的框架
(2)框架处理完数据会返回给服务器,服务器会把数据发送给浏览器
(3)框架中包含很重要的函数,当框架写好后,只需要关心函数的执行
(4)框架只需要让我们关心页面显示什么
2. 运行写好的服务器
import socket
import re
import multiprocessing
import mini_web
class WebServer(object):
"""这个服务器类"""
def __init__(self):
"""初始化tcp服务器"""
# 1. 创建套接字
self.tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 2. 绑定
self.tcp_server_socket.bind(("", 8899))
# 3. 变为监听套接字
self.tcp_server_socket.listen(128)
def service_client(self, new_socket):
"""为这个客户端返回数据"""
# 1. 接收浏览器发送过来的请求 ,即http请求
# GET / HTTP/1.1
# .....
request = new_socket.recv(1024).decode("utf-8")
request_lines = request.splitlines()
print("")
print(">" * 20)
print(request_lines)
# GET /index.html HTTP/1.1
# get post put del
file_name = ""
ret = re.match(r"[^/]+(/[^ ]*)", request_lines[0])
if ret:
file_name = ret.group(1)
# print("*"*50, file_name)
if file_name == "/":
file_name = "/index.html"
# 如果是html那么会调用mini_web上的application返回页面数据
if file_name.endswith(".html"): # 伪静态,动态改装成静态代码,一般就是后缀改成.html
url_params = dict() # 给mini_web传参数的
url_params['file_name'] = file_name
body = mini_web.application(url_params, self.head_params) # 调用框架处理
head = "HTTP/1.1 %s\r\n" % self.stauts
# 拼接我们的响应头
for temp in self.params:
head += "%s:%s\r\n" % temp
content = head + "\r\n" + body
new_socket.send(content.encode("utf-8"))
else:
# 返回静态的数据
# 2. 返回http格式的数据,给浏览器
try:
f = open("./static" + file_name, "rb")
except:
response = "HTTP/1.1 404 NOT FOUND\r\n"
response += "\r\n"
response += "------file not found-----"
new_socket.send(response.encode("utf-8"))
print("文件找不到!")
else:
html_content = f.read()
f.close()
# 2.1 准备发送给浏览器的数据---header
response = "HTTP/1.1 200 OK\r\n"
response += "\r\n"
# 2.2 准备发送给浏览器的数据---boy
# response += "hahahhah"
# 将response header发送给浏览器
new_socket.send(response.encode("utf-8"))
# 将response body发送给浏览器
new_socket.send(html_content)
# 关闭套接
new_socket.close()
def run_server(self):
"""用来完成整体的控制"""
while True:
# 4. 等待新客户端的链接
new_socket, client_addr = self.tcp_server_socket.accept()
# 5. 为这个客户端服务
p = multiprocessing.Process(target=self.service_client, args=(new_socket,))
p.start()
new_socket.close()
# 关闭监听套接字
tcp_server_socket.close()
def head_params(self, stauts, params):
""" 把响应头存起来进行后期的拼接"""
self.stauts = stauts
self.params = params
def main():
server = WebServer()
server.run_server()
if __name__ == "__main__":
main()
3. 在写好的框架里直接执行函数部分
(1)框架部分
import re
from urllib.request import unquote # 解码
# 定义空字典,用来存储路径跟对应的函数引用
from pymysql import connect
# 这个是路径跟方法的函数
url_dict = dict()
# start_response用来框架给服务器传响应头的数据
# environ用来得到服务器传过来的文件路径
def application(environ, start_response):
"""返回具体展示的界面给服务器"""
start_response('200 OK', [('Content-Type', 'text/html;charset=utf-8')]) # 返回响应头
# 根据不同的地址进行判断
file_name = environ['file_name']
for key, value in url_dict.items():
match = re.match(key, file_name) # 你的地址跟你的规则一致
if match:
# 匹配了
return value(match) # 调用匹配到的函数引用,返回匹配的页面内容
else:
# 说明没找到
return "not page is find!"
# 这个装饰器传参,用来完成路由的功能def route(url_address): # url_address表示页面的路径
"""主要的目的自动添加路径跟匹配的函数到我们的url字典中"""
def set_fun(func):
def call_fun(*args, **kwargs):
return func(*args, **kwargs)
# 根据不同的函数名称去添加到字典中
url_dict[url_address] = call_fun
return call_fun
return set_fun
(2)函数的执行: 显示一个简单的从前端获取的网页界面,可以实现数据的增删改查
@route("/index.html")
def index(match):
""" 显示股票界面 """
"""
1. 打开前端给的网页界面
2. 连接数据库导入数据
3. 拼接数据到表格中
4. 返回数据
"""# 打开前端给的网页
with open("./templates/index.html") as f:
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 = connect(host='localhost', port=3306, user='root', password='mysql', database='stock_db', charset='utf8')
# 得到游标
cs1 = conn.cursor()
# 执行sql语句
sql = '''select * from info;'''
print(sql)
cs1.execute(sql)
# 得到数据
data = cs1.fetchall()
# 打印所有数据
for temp in data:
print(temp)
# 关闭
cs1.close()
conn.close()
# 定义表格的数据
table_str = ""
for temp in data:
table_str += row_str % (temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], temp[7], temp[1])
# 使用正则替换我们的数据
content_new = re.sub(r'\{%content%\}', table_str, content)
return content_new
@route("/center.html")
def center(match):
""" 显示个人界面 """
# 打开前端给的网页
with open("./templates/center.html") as f:
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/%s.html"> <span class="glyphicon glyphicon-star" aria-hidden="true"></span> 修改 </a>
</td>
<td>
<input type="button" value="删除" id="toDel" name="toDel" systemidvaule="%s">
</td>
</tr>"""
# 链接数据库得到数据
# 链接数据库
conn = connect(host='localhost', port=3306, user='root', password='mysql', database='stock_db', charset='utf8')
# 得到游标
cs1 = conn.cursor()
# 执行sql语句
sql = ''' select info.code,info.short,info.chg,info.turnover,info.price,info.highs,focus.note_info from focus inner join info on focus.info_id = info.id; '''
print(sql)
cs1.execute(sql)
# 得到数据
data = cs1.fetchall()
# 打印所有数据
for temp in data:
print(temp)
# 关闭
cs1.close()
conn.close()
# 定义表格中的数据
table_str = ""
for temp in data:
table_str += row_str % (temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], temp[0], temp[0])
# 拼接数据
content_new = re.sub(r"\{%content%\}", table_str, content)
# 返回数据
return content_new
# 接下来执行数据的增删改查
"""添加"""
@route("/add/(\d+).html")
def add(match):
"""对数据进行判断:存在无法添加,不存在就添加"""
# 得到code 进行操作
code = match.group(1)
# 链接数据库进行操作
conn = connect(host='localhost', port=3306, user='root', password='mysql', database='stock_db', charset='utf8')
# 得到游标
cs1 = conn.cursor()
# 执行sql语句
sql = ''' select * from focus where info_id in (select id from info where code = %s); '''
cs1.execute(sql, (code,))
# 判断是否有数据
if cs1.fetchone():
"""已经有数据"""
cs1.close()
conn.close()
return "亲?已经有数据了"
else:
"""没有数据"""
sql = """ insert into focus(info_id) (select id from info where code = %s); """
cs1.execute(sql, (code,))
# 修改完提交数据
conn.commit()
# 关闭
conn.close()
cs1.close()
# 返回数据
return "亲?添加成功"
"""删除"""
@route("/del/(\d+).html")
def delete_data(match):
"""根据code去删除数据"""
# 得到code
code = match.group(1)
# 链接数据库得到数据
conn = connect(host='localhost', port=3306, user='root', password='mysql', database='stock_db', charset='utf8')
# 得到游标
cs1 = conn.cursor()
# 执行sql语句
sql = '''delete from focus where info_id in (select id from info where code = %s);'''
print(sql)
cs1.execute(sql, (code,))
# 得到数据
data = cs1.fetchall()
# 打印所有数据
for temp in data:
print(temp)
# 提交数据conn.commit()
# 关闭
cs1.close()
conn.close()
# 返回数据
return "亲,删除成功"
"""更新"""
@route("/update/(\d+).html")
def update(match):
"""显示一个新的界面"""
# 得到code
code = match.group(1)
# 从前端给的网页里打开内容
with open("./templates/update.html")as f:
content = f.read()
# 替换我们的code
content = re.sub(r"\{%code%\}", code, content)
# 链接数据库得到数据
conn = connect(host='localhost', port=3306, user='root', password='mysql', database='stock_db', charset='utf8')
# 得到游标
cs1 = conn.cursor()
# 执行sql语句
sql = '''select note_info from focus where info_id in(select id from info where code = %s);;'''
print(sql)
cs1.execute(sql, (code,))
# 得到数据
data = cs1.fetchall()
# 打印所有数据
for temp in data:
print(temp)
# 关闭
cs1.close()
conn.close()
# 得到数据
print(data[0][0])
# 将数据替换
content = re.sub(r"\{%note_info%\}", data[0][0], content)
# 返回数据
return content
"""接下来更新数据"""
@route("/update/(\d+)/(.*).html")
def update_data(match):
# 获取code
code = match.group(1)
# 获取内容
note_info = match.group(2)
# 链接数据库获取数据
conn = connect(host='localhost', port=3306, user='root', password='mysql', database='stock_db', charset='utf8')
# 得到游标
cs1 = conn.cursor()
# 执行sql语句
sql = '''update focus set note_info = %s where info_id in (select id from info where code = %s);'''
print(sql)
cs1.execute(sql, (note_info, code))
# 得到数据
data = cs1.fetchall()
# 打印所有数据
for temp in data:
print(temp)
# 提交数据
conn.commit()
# 关闭
cs1.close()
conn.close()
# 返回数据
return " 更新成功 "
(4)在浏览器输入ip地址和端口号进行访问即可