说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家!
目录
一丶项目说明
二丶数据准备
三丶使用网络TCP开发一个基于WSGI协议的Web服务器
四丶使用python3开发一个轻量级的Web框架
五丶在框架中实现添加股票功能
六丶在框架中实现删除股票功能
七丶在框架中实现修改股票功能
1.实现过程
用户通过浏览器向Web服务器请求资源,Web服务器基于WSGI协议调用Web框架中application接口函数,在application函数中根据用户请求地址,匹配路由规则,匹配成功后调用请求地址对应的视图函数,在视图函数中主要操作为对MySQL数据库的增删改查以及读取html页面模板内容,然后将模板中需要填充的数据与MySQL返回的数据进行字符串拼接,然后返回给Web服务器,最终Web服务器将拿到的数据当作响应体数据,并与状态码和响应头进行拼接后返回给浏览器,在浏览器上呈现用户想要看到的资源数据
2.最终效果展示
3.效果动图
1.在MySQL中创建stock_db数据库
create database stock_db charset=utf8;
2.在stock_db数据库下创建股票信息表info
3.在stock_db数据库下创建关注信息表focus
4.向focus表中的info_id字段添加info表的id外键
5.插入表数据
INSERT INTO `info` VALUES (1,'000007','全新好','10.01%','4.40%',16.05,14.60,'2019-03-18'),(2,'000036','华联控股','10.04%','10.80%',11.29,10.26,'2019-03-20'),(3,'000039','中集集团','1.35%','1.78%',18.07,18.06,'2019-02-28'),(4,'000050','深天马A','4.38%','4.65%',22.86,22.02,'2019-03-19'),(5,'000056','皇庭国际','0.39%','0.65%',12.96,12.91,'2019-03-20'),(6,'000059','华锦股份','3.37%','7.16%',12.26,12.24,'2018-12-11'),(7,'000060','中金岭南','1.34%','3.39%',12.08,11.92,'2019-03-20'),(8,'000426','兴业矿业','0.41%','2.17%',9.71,9.67,'2019-03-20'),(9,'000488','晨鸣纸业','6.30%','5.50%',16.37,15.59,'2019-03-10'),(10,'000528','柳工','1.84%','3.03%',9.42,9.33,'2019-03-19'),(11,'000540','中天金融','0.37%','5.46%',8.11,8.08,'2019-03-20'),(12,'000581','威孚高科','3.49%','3.72%',27.00,26.86,'2019-02-26'),(13,'000627','天茂集团','5.81%','12.51%',10.93,10.33,'2019-03-20'),(14,'000683','远兴能源','6.42%','21.27%',3.48,3.29,'2019-03-19'),(15,'000703','恒逸石化','0.24%','1.65%',16.92,16.88,'2019-03-20'),(16,'000822','山东海化','6.60%','8.54%',9.05,8.75,'2019-03-06'),(17,'000830','鲁西化工','1.38%','4.80%',7.36,7.26,'2019-03-20'),(18,'000878','云南铜业','1.26%','3.23%',14.50,14.47,'2019-03-19'),(19,'000905','厦门港务','5.44%','10.85%',15.90,15.60,'2018-12-20'),(20,'000990','诚志股份','0.53%','1.00%',16.99,16.90,'2019-03-20'),(21,'002019','亿帆医药','1.19%','2.81%',17.05,16.85,'2019-03-20'),(22,'002078','太阳纸业','2.05%','1.90%',8.45,8.29,'2019-03-19'),(23,'002092','中泰化学','7.25%','6.20%',15.53,14.48,'2019-03-20'),(24,'002145','中核钛白','2.43%','7.68%',6.75,6.61,'2019-03-19'),(25,'002285','世联行','8.59%','5.66%',9.23,8.50,'2019-03-20'),(26,'002311','海大集团','1.13%','0.24%',18.81,18.63,'2019-03-19'),(27,'002460','赣锋锂业','9.41%','9.00%',63.70,58.22,'2019-03-20'),(28,'002466','天齐锂业','3.62%','3.66%',68.44,66.05,'2019-03-20'),(29,'002470','金正大','2.30%','0.99%',8.00,7.82,'2019-03-20'),(30,'002496','辉丰股份','3.15%','4.29%',5.24,5.08,'2018-12-10'),(31,'002497','雅化集团','0.38%','12.36%',13.10,13.05,'2019-03-20'),(32,'002500','山西证券','0.44%','3.70%',11.49,11.44,'2019-03-20'),(33,'002636','金安国纪','2.70%','11.59%',19.80,19.42,'2019-03-19'),(34,'300032','金龙机电','0.66%','0.72%',15.28,15.18,'2019-03-20'),(35,'300115','长盈精密','0.60%','0.59%',33.50,33.41,'2019-03-19'),(36,'300268','万福生科','-10.00%','0.27%',31.77,13.57,'2018-12-10'),(37,'300280','南通锻压','3.31%','0.66%',32.20,32.00,'2018-12-11'),(38,'300320','海达股份','0.28%','0.82%',18.26,18.21,'2019-03-20'),(39,'300408','三环集团','1.69%','0.81%',23.42,23.17,'2019-03-19'),(40,'300477','合纵科技','2.84%','5.12%',22.10,22.00,'2019-03-12'),(41,'600020','中原高速','5.46%','4.48%',5.60,5.31,'2019-03-20'),(42,'600033','福建高速','1.01%','1.77%',4.00,3.99,'2019-02-26'),(43,'600066','宇通客车','4.15%','1.49%',23.08,23.05,'2019-02-13'),(44,'600067','冠城大通','0.40%','2.97%',7.56,7.53,'2019-03-20'),(45,'600110','诺德股份','2.08%','4.26%',16.16,15.83,'2019-03-20'),(46,'600133','东湖高新','9.65%','21.74%',13.64,12.44,'2019-03-20'),(47,'600153','建发股份','3.65%','2.03%',13.35,13.21,'2019-03-10'),(48,'600180','瑞茂通','2.20%','1.07%',14.86,14.54,'2019-03-20'),(49,'600183','生益科技','6.94%','4.06%',14.94,14.12,'2019-03-19'),(50,'600188','兖州煤业','1.53%','0.99%',14.56,14.43,'2019-03-19'),(51,'600191','华资实业','10.03%','11.72%',15.80,14.36,'2019-03-20'),(52,'600210','紫江企业','6.03%','10.90%',6.68,6.30,'2019-03-20'),(53,'600212','江泉实业','1.39%','1.78%',10.20,10.15,'2019-03-19'),(54,'600225','*ST松江','4.96%','2.47%',5.71,5.61,'2018-12-13'),(55,'600230','沧州大化','5.74%','13.54%',43.26,40.91,'2019-03-20'),(56,'600231','凌钢股份','2.79%','3.77%',3.68,3.60,'2019-03-19'),(57,'600291','西水股份','10.02%','9.23%',34.71,31.55,'2019-03-20'),(58,'600295','鄂尔多斯','4.96%','12.62%',16.51,15.73,'2019-03-20'),(59,'600303','曙光股份','8.37%','14.53%',11.53,10.64,'2019-03-20'),(60,'600308','华泰股份','1.12%','2.66%',6.30,6.26,'2019-03-19'),(61,'600309','万华化学','0.03%','1.78%',31.81,31.80,'2019-03-20'),(62,'600352','浙江龙盛','0.39%','1.85%',10.32,10.28,'2019-03-20'),(63,'600354','敦煌种业','7.89%','18.74%',9.44,8.75,'2019-03-20'),(64,'600408','安泰集团','1.98%','3.38%',4.13,4.12,'2018-12-13'),(65,'600409','三友化工','0.62%','3.78%',11.36,11.29,'2019-03-20'),(66,'600499','科达洁能','0.46%','3.94%',8.84,8.80,'2019-03-20'),(67,'600508','上海能源','3.26%','2.99%',13.32,13.01,'2019-03-19'),(68,'600563','法拉电子','0.32%','1.36%',53.67,53.50,'2019-03-20'),(69,'600567','山鹰纸业','0.76%','2.85%',3.98,3.96,'2019-03-19'),(70,'600585','海螺水泥','0.45%','0.61%',24.51,24.44,'2019-03-19'),(71,'600668','尖峰集团','4.35%','6.43%',18.70,18.36,'2018-12-13'),(72,'600688','上海石化','2.72%','0.91%',6.80,6.74,'2019-02-01'),(73,'600729','重庆百货','5.70%','3.34%',27.45,27.13,'2019-02-28'),(74,'600739','辽宁成大','3.30%','3.50%',19.74,19.11,'2019-03-20'),(75,'600779','水井坊','3.85%','2.77%',29.39,28.30,'2019-03-20'),(76,'600781','辅仁药业','8.61%','4.16%',23.46,21.89,'2019-01-02'),(77,'600801','华新水泥','4.00%','10.15%',12.99,12.49,'2019-03-20'),(78,'600846','同济科技','2.06%','17.41%',9.39,9.26,'2018-12-13'),(79,'600884','杉杉股份','1.08%','3.53%',20.67,20.45,'2019-03-20'),(80,'600966','博汇纸业','2.89%','5.54%',6.41,6.28,'2019-03-19'),(81,'600971','恒源煤电','2.36%','8.81%',12.16,11.88,'2019-03-20'),(82,'601012','隆基股份','0.76%','1.30%',19.93,19.78,'2019-03-20'),(83,'601100','恒立液压','4.78%','0.92%',19.31,18.97,'2019-03-13'),(84,'601101','昊华能源','4.03%','6.06%',11.10,10.80,'2019-03-19'),(85,'601216','君正集团','2.16%','2.26%',5.20,5.10,'2018-12-17'),(86,'601666','平煤股份','2.81%','6.14%',6.96,6.77,'2019-03-20'),(87,'601668','中国建筑','2.39%','1.42%',10.70,10.45,'2019-03-20'),(88,'601678','滨化股份','0.13%','2.47%',7.92,7.91,'2019-03-20'),(89,'601918','新集能源','1.23%','3.11%',4.93,4.92,'2019-03-19'),(90,'603167','渤海轮渡','2.77%','3.34%',11.87,11.61,'2018-12-13'),(91,'603369','今世缘','3.34%','2.13%',14.24,13.78,'2019-03-20'),(92,'603589','口子窖','3.99%','1.84%',39.37,39.04,'2019-02-26'),(93,'603799','华友钴业','2.38%','7.19%',67.46,65.89,'2019-03-20'),(94,'603993','洛阳钼业','2.94%','2.50%',7.36,7.16,'2019-03-19');
INSERT INTO `focus` VALUES (1,'先试一试',30),(2,'非常稳',38),(3,'一般般',78),(12,'不咋地',80),(17,'',23);
6.查询表数据
1.创建工程目录以及文件
说明:dynamic目录----存放动态资源,static目录----存放静态资源,templates目录----存放模板文件
server.conf----服务器配置文件,web_server.py----服务器启动文件
2.服务器文件web_server.py代码实现
import socket
import multiprocessing
class WSGIServer(object):
def __init__(self):
pass
def main():
pass
if __name__ == '__main__':
main()
self.tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.tcp_server_socket.bind(("", 7979))
self.tcp_server_socket.listen(128)
while True:
client_socket, client_addr = self.tcp_server_socket.accept()
# 使用进程中的子线程来完成客户端的连接处理
p = multiprocessing.Process(target=self.handle_client, args=(client_socket,))
p.start()
client_socket.close()
tcp_server_socket.close()
def handle_client(client_socket):
request_data = client_socket.recv(1024).decode("utf-8")
print(request_data)
request_lines = request_data.splitlines()
# print(request_lines)
result = re.match(r"[^/]+([^ ]*)", request_lines[0])
if result:
# print(result.group(1)+"*"*10)
file_name = result.group(1)
try:
with open("./html"+file_name, "rb") as f:
server_response_body = f.read()
except:
server_response = "HTTP/1.1 404 NOT FOUND \r\n"
server_response += "\r\n"
server_response += "-----File Not Found-----"
client_socket.send(server_response.encode("utf-8"))
else:
server_response_header = "HTTP/1.1 200 OK \r\n"
server_response_header += "\r\n"
client_socket.send(server_response_header.encode("utf-8"))
client_socket.send(server_response_body)
client_socket.close()
3.让该TCP服务器遵循WSGI协议
def index():
return "this is index page!"
def login():
return "this is login page!"
def application(environ, start_response):
pass
# 以.py为结尾表示请求动态资源否则为静态资源
if not file_name.endswith(".py"):
try:
with open("../html"+file_name, "rb") as f:
server_response_body = f.read()
except:
server_response = "HTTP/1.1 404 NOT FOUND \r\n"
server_response += "\r\n"
server_response += "-----File Not Found-----"
client_socket.send(server_response.encode("utf-8"))
else:
server_response_header = "HTTP/1.1 200 OK \r\n"
server_response_header += "\r\n"
client_socket.send(server_response_header.encode("utf-8"))
client_socket.send(server_response_body)
else:
"""遵循WSGI协议"""
# 1.导入定义的web_frame框架,模拟WSGI调用过程
import web_frame
# 2.调用框架中的application方法
env = dict()
# print(file_name) /index.py
env["PATH_INFO"] = file_name #{'PATH_INFO':'/index.py'}
body = web_frame.application(env, self.start_response)
# print(body, env)
server_response_header = "HTTP/1.1 %s \r\n" % self.status
for temp in self.header:
server_response_header += '%s:%s\r\n' %(temp[0], temp[1])
server_response_header += "\r\n"
# server_response_body = "这是动态资源 %s
" % time.ctime()
server_response_data = server_response_header + body
client_socket.send(server_response_data.encode("utf-8"))
client_socket.close()
# 3.定义start_response函数
def start_response(self, status, header):
self.status = status
self.header = [("server"," web_frame/1.0")]
self.header += header
def application(environ, start_response):
file_name = environ['PATH_INFO']
start_response('200 OK', [('Content-Type', ' text/html;charset=utf-8')])
if file_name == "/index.py":
return index()
elif file_name == "/login.py":
return login()
else:
return 'Hello World! 你好 中国!'
4.在浏览器中渲染出网页模板文件
首页 - 个人选股系统 V5.87
序号
股票代码
股票简称
涨跌幅
换手率
最新价(元)
前期高点
前期高点日期
添加自选
{%content%}
个人中心 - 个人选股系统 V5.87
股票代码
股票简称
涨跌幅
换手率
最新价(元)
前期高点
备注信息
修改备注
删除
{%content%}
if not file_name.endswith(".html"):
# print(self.static_path_+file_name)
try:
with open("./static" + file_name, "rb") as f:
server_response_body = f.read()
except:
server_response = "HTTP/1.1 404 NOT FOUND \r\n"
server_response += "\r\n"
server_response += "-----File Not Found-----"
client_socket.send(server_response.encode("utf-8"))
else:
server_response_header = "HTTP/1.1 200 OK \r\n"
server_response_header += "\r\n"
client_socket.send(server_response_header.encode("utf-8"))
client_socket.send(server_response_body)
else:
"""遵循WSGI协议"""
# 1.导入定义的web_frame框架,模拟WSGI调用过程
import web_frame
# 2.调用框架中的application方法
env = dict()
# print(file_name) /index.html
env["PATH_INFO"] = file_name #{'PATH_INFO':'/index.html'}
env["page_num"] = 1
body = web_frame.application(env, self.start_response)
# print(body, env)
# print(body, "5555555555")
server_response_header = "HTTP/1.1 %s \r\n" % self.status
for temp in self.header:
server_response_header += '%s:%s\r\n' %(temp[0], temp[1])
server_response_header += "\r\n"
# server_response_body = "这是动态资源 %s
" % time.ctime()
server_response_data = server_response_header + body
client_socket.send(server_response_data.encode("utf-8"))
client_socket.close()
if result:
# print(result.group(1)+"*"*10)
file_name = result.group(1)
if file_name == "/":
file_name = "/index.html"
# print(file_name,"qwqwqwq")
def index():
with open("./templates/index.html",encoding="utf-8") as f:
content = f.read()
return content
def center():
with open("./templates/center.html") as f:
return f.read()
def application(env, start_response):
start_response('200 OK', [('Content-Type', 'text/html;charset=utf-8')])
file_name = env['PATH_INFO']
# file_name = "/index.html"
if file_name == "/index.html":
return index()
elif file_name == "/center.html":
return center()
else:
return 'Hello World! 你好 中国!'
def run_forever(self):
while True:
client_socket, client_addr = self.tcp_server_socket.accept()
# 使用进程中的子线程来完成客户端的连接处理
p = multiprocessing.Process(target=self.handle_client, args=(client_socket,))
p.start()
client_socket.close()
# handle_client(client_socket)
tcp_server_socket.close()
def main():
WSGIServer().run_forever()
5.以解释器 程序 端口号 框架名:方法,如python3 web_server.py 7979 web_frame:application运行此程序
{
"static_path":"./static",
"dynamic_path":"./dynamic"
}
with open("./server.conf") as f:
config = eval(f.read())
port = int(sys.argv[1])
frame_app = sys.argv[2].split(':')
frame_name = frame_app[0]
app_name = frame_app[1]
sys.path.append(config["dynamic_path"])
frame = __import__(frame_name) #__import__方法以变量的值去导入模块 返回对象
app = getattr(frame, app_name) # getattr返回函数
WSGIServer(port, app, config['static_path']).run_forever()
在__init__方法中
def __init__(self, port, app, static_path):
self.tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.tcp_server_socket.bind(("", port))
self.tcp_server_socket.listen(128)
self.application = app
self.static_path = static_path
在handle_client方法中
"""遵循WSGI协议"""
# 2.调用框架中的application方法
env = dict()
# print(file_name) /index.py
env["PATH_INFO"] = file_name #{'PATH_INFO':'/index.py'}
env["page_num"] = 1
body = self.application(env, self.start_response)
# print(body, env)
# print(body, "5555555555")
server_response_header = "HTTP/1.1 %s \r\n" % self.status
for temp in self.header:
server_response_header += '%s:%s\r\n' %(temp[0], temp[1])
server_response_header += "\r\n"
# server_response_body = "这是动态资源 %s
" % time.ctime()
server_response_data = server_response_header + body
client_socket.send(server_response_data.encode("utf-8"))
1.在web_frame.py框架文件中,使用装饰器完成路由功能
URL_FUNC_DICT = dict()
def route(url):
def set_func(func):
# URL_FUNC_DICT["/index.html"] = index
URL_FUNC_DICT[url] = func
def call_func(*args, **kwargs):
return func(*args, **kwargs)
return call_func
return set_func
@route("/index.html")
def index():
with open("./templates/index.html",encoding="utf-8") as f:
content = f.read()
return content
@route("/center.html")
def center():
with open("./templates/center.html") as f:
return f.read()
def application(env, start_response):
start_response('200 OK', [('Content-Type', 'text/html;charset=utf-8')])
file_name = env['PATH_INFO']
try:
return URL_FUNC_DICT[file_name]()
except Exception as ret:
return "产生了异常:%s" % str(ret)
2.让路由支持正则匹配规则
for url, func in URL_FUNC_DICT.items():
# {
# r"/index.html":index,
# r"/center.html":center,
# }
ret = re.match(url, file_name)
if ret:
return func()
else:
return "请求的url(%s)没有对应的函数...." % file_name
@route(r"/index.html")
def index():
with open("./templates/index.html",encoding="utf-8") as f:
content = f.read()
return content
@route(r"/center.html")
def center():
with open("./templates/center.html") as f:
return f.read()
3.将数据库中的数据显示到index.html以及center.html网页中
def connect_db(sql):
conn = connect(host="localhost",port=3306,user="root",password="mysql",database="stock_db",charset="utf8")
cs = conn.cursor()
cs.execute(sql)
info_data = cs.fetchall()
if sql.startswith("select"):
conn.close()
cs.close()
else:
conn.commit()
cs.close()
return info_data
with open("./templates/index.html", encoding="utf-8") as f:
content = f.read()
info_data = connect_db("select * from info;")
info_template= """
%s
%s
%s
%s
%s
%s
%s
%s
"""
html_data = ""
for temp in info_data:
html_data += info_template % (temp[0],temp[1],temp[2],temp[3],temp[4],temp[5],temp[6],temp[7],temp[1]) #后面加的temp[1]股票代码是为了填充添加列systemidvaule得值
content = re.sub(r"\{%content%\}",html_data,content)
return content
with open("./templates/center.html", encoding="utf-8") as f:
content = f.read()
info_data = connect_db("select i.code,i.short,i.chg,i.turnover,i.price,i.highs,f.not_info from info as i inner join focus as f on i.id = f.info_id;")
info_template = """
%s
%s
%s
%s
%s
%s
%s
修改
"""
html_data = ""
for temp in info_data:
html_data += info_template % (temp[0],temp[1],temp[2],temp[3],temp[4],temp[5],temp[6],temp[0],temp[0])
content = re.sub(r"\{%content%\}",html_data,content)
return content
4.将主页index.html数据进行分页显示
page_template = """
"""
content = re.sub(r"\{%page%\}",page_template,content)
page_num = re.match(r".*page=(\d+)",request_lines[0])
if page_num:
page_num = page_num.group(1)
# print(type(page_num))
if file_name.endswith("page=%s" % page_num):
env = dict()
# print(file_name) /index.py
env["PATH_INFO"] = "/index.html" # {'PATH_INFO':'/index.py'}
env["page_num"] = page_num
body = self.application(env, self.start_response)
def application(environ, start_response):
file_name = environ['PATH_INFO']
page_num = environ["page_num"]
start_response('200 OK', [('Content-Type', ' text/html;charset=utf-8')])
for url, func in URL_FUNC_DICT.items():
ret = re.match(url, file_name)
# print(ret,"wwwwwwwwwwwwww")
if ret:
# print(ret.group(1))
return func(page_num)
else:
return "请求的url(%s)地址不存在..." % file_name
page_num = int(page_num)
with open("./templates/index.html", encoding="utf-8") as f:
content = f.read()
total_page = connect_db("select count(*) from info;")
if (page_num-1)*12 > total_page[0][0]:
html_data = "没有更多的数据了.....
"
content = re.sub(r"\{%content%\}", html_data, content)
content = re.sub(r"\{%page%\}", "", content)
return content
info_data = connect_db("select * from info limit %d,%d;" %((page_num-1)*12,12))
1.在index.html中编写以下JS,点击添加按钮则向http://127.0.0.1:7979/add/code.html地址发送请求,其中code为股票代码,通过js中的attr方法获取模板中systemIdvalue的值也就是股票代码
@route(r"/del/(\d+)\.html")
def del_focus(page_num, ret):
pass
# 1. 获取添加按钮触发的ajax请求地址中的股票代码
stock_code = ret.group(1)
# print(stock_code)
# 2.判断获取到的股票代码是否存在
res = connect_db("select * from info where code = '%s'" % stock_code)
if not res:
return "非法请求"
# 3.判断该股票是否已经关注,未关注表示非法删除请求
res = connect_db("select * from info as i inner join focus as f on i.id = f.info_id where i.code = '%s'" % stock_code)
if not res:
return "该股票未关注...."
# 4.取关股票,并修改info表中is_add字段为0表示在页面显示添加按钮
connect_db("delete from focus where info_id = (select id from info where code = '%s')" % stock_code)
connect_db("update info set is_add = 0 where code = '%s'" % stock_code)
return "取关股票成功"
3.进行测试
1.在templates模板目录下创建update.html文件,代码如下
首页 - 个人选股系统 V5.87
正在修改:
{%code%}
修改
2.在update.html文件中编写如下js,当用户点击修改按钮,首先当用户在个人中心页面对股票点击修改时,向http://127.0.0.1:7979/update/300320.html地址发送请求进入到修改界面,然后在修改界面点击修改时,向http://127.0.0.1:7979/update/000581/备注信息.html地址发送请求,获取响应内容最后跳转到个人中心网页
3.在框架文件中创建show_update_page视图函数,用于显示修改备注信息页面
修改
@route(r"/update/(\d+)\.html")
def show_update_page(page_num, ret):
"""显示修改界面"""
# 1.读取修改界面代码
with open("./templates/update.html", encoding="utf-8") as f:
content = f.read()
# 2. 获取要修改的股票代码
stock_code = ret.group(1)
# 3. 获取该关注股票的备注信息
res = connect_db("select f.not_info from info as i inner join focus as f on i.id = f.info_id where i.code = '%s'" % stock_code)
not_info = res[0][0]
# print(not_info, "wwwwwwwwwwwww")
# 4. 替换html中的空缺两次依次替换
content = re.sub(r"\{%note_info%\}", not_info, content)
content = re.sub(r"\{%code%\}", stock_code, content)
return content
4.在框架文件中定义save_update_data视图函数用于保存股票修改后的备注信息
@route(r"/update/(\d+)/(.*)\.html")
def save_update_data(page_num, ret):
"""将用户修改的备注信息保存到数据库"""
# 1. 获取股票代码以及备注信息
stock_code = ret.group(1)
comment = ret.group(2)
# 2. 因之前添加关注功能对股票信息进行了验证,所以在个人中心页面的已关注的股票信息为合法信息,所以直接写入数据库即可
connect_db("update focus set not_info = '%s' where info_id = (select id from info where code = %s)" %(comment, stock_code))
return """修改备注信息成功"""
comment = urllib.parse.unquote(comment)
5.这个项目有很多需要优化以及不足的地方,所有的Web项目大同小异都是这个流程,代码不重要,重要的是明白浏览器服务器以及程序框架之间数据是怎么传递的