前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >web服务器进阶

web服务器进阶

作者头像
不断折腾
发布2019-09-23 10:52:09
4.3K0
发布2019-09-23 10:52:09
举报
通过上面的学习,我们发现我们的web服务器没有彻底解耦

1、实现自己指定端口运行我们的web服务器

如果我们的web服务器端口被占用,那么我们的web服务器直接挂掉。

怎么实现?我们可以在执行的时候指定一个端口。

复习:

创建一个Demo.py

写上:

import sys

print(sys.argv)

我们在黑窗口运行一个python文件的时候,执行命令:

python Demo 123 456

会输出:['Demo.py', '123', '456']

可见,我们是可以给一个程序传递参数的。我们用这个功能,来给我们的web服务器指定端口和框架。

2、利用1中的例子,再给一个框架名,让他直接传一个框架进入。

我们希望运行 python web服务器 7891 Demo:application

来实现调用Demo框架的application方法。

3、写一个配置文件,将web服务器中的寻找文件的路径写进去。

解决上面三个问题才是真的解耦。

思路已经提供给大家,并且看基础是能够写出来的。

接下来我们利用装饰器完成路由功能。对装饰器不懂的可以看看这篇文章:python基础三

什么是路由功能?

就是请求的url,我们上次通过if判断来写的,很恶心,用另一种方法些

我们将Demo框架写成这样(不用再修改web服务器了):

URL_FUNC_DICT = dict()

def url_func(url):

def set_fun(func):

URL_FUNC_DICT[url] = func

def call_func(*args,**kwargs):

return func(*args,**kwargs)

return call_func

return set_fun

@url_func('/login.py')

def login():

# 这里也可以读取文件

return '<h1>登录的页面</h1>'

@url_func('/create.py')

def create():

return '<h1>注册的页面</h1>'

def application(evairon,start_response):

# 第一个参数返回状态码,第二个以键值的方式返回你想添加的head部分

start_response('200 ok',[('Content-Type','text/html;charset=utf-8')])

# 返回给网页的内容

try:

file_name = evairon['path_info']

fun = URL_FUNC_DICT[file_name]

return fun()

except Exception as e:

return '未找到文件'

伪静态实现

在前面说过我们只是暂时任务请求以.py结尾的url为动态的。实际上不是这样。

上面才是动态网页?

静态的:域名/index.html

动态的:域名/index.aspx?page=xxx&xxxxx=xxxx,

伪静态:域名/cour/index.html

web服务器实现伪静态:

修改web服务器中判断是.py结尾为以.html结尾,其它不用管。

修改Demo框架中装饰器的参数为.html结尾。

给Demo框架连接数据库并显示到页面

数据库运用我们mysql教程中给大家演示的那个student数据库。

对于python操作数据库没了解的请去看mysql数据库系列文章。

mysql简单基础,我们在Demo新创建一个mysqldata方法,并且加上装饰器

@url_func('/mysqldata.html')

def mysqldata():

conn = connect(host='localhost',port=3306,user='root',password='123456',database='student',charset='utf8')

cursor = conn.cursor()

cursor.execute("select * from studentinfo")

text = cursor.fetchall()

cursor.close()

conn.close()

return str(text)

在浏览器中输入127.0.0.1:端口号/mysqldata.html即可看到内容。

查出来是这样的:((1, '张三', 1, '男', 23, '武汉', b'\x00'), (2, '小花', 2, '女', 20, '长沙', b'\x00'), (3, '李四', 3, '男', 21, '上海', b'\x00'), (4, '小猫', 1, '女', 18, '北京', b'\x00'), (6, '小狗', 3, '女', 25, '成都', b'\x00'), (7, '赵六', 1, '男', 26, '天津', b'\x00'))

看着很恶心,给个格式。修改mysqldata方法:

这里会用到html的知识点,希望自己补充。修改成:

@url_func('/mysqldata.html')

def mysqldata():

conn = connect(host='localhost',port=3306,user='root',password='123456',database='student',charset='utf8')

cursor = conn.cursor()

cursor.execute("select * from studentinfo")

text = cursor.fetchall()

cursor.close()

conn.close()

html = "<table border='1' width = '400px' cellspacing='0' cellpadding='0'>"

tr_html = '''

<tr>

<td>%s</td>

<td>%s</td>

<td>%s</td>

<td>%s</td>

<td>%s</td>

<td>%s</td>

<td>%s</td>

</tr>

'''

for item in text:

html += tr_html %(item[0],item[1],item[2],item[3],item[4],item[5],item[6])

html +="</table>"

return str(html)

这样就好看多了。当然你想显示什么就数据库查什么就好了。

完善Demo框架

1、给路由添加正则

现在我们的url返回的都是固定的,比如我们想要删除一个数据,请求的url为/delete/xxx.html

我们需要传递一个xxx,表示id,这个id是不确定的,所以我们需要正则匹配,只要是这种格式,我们都执行

delete方法。修改如下:

修改application方法:

def application(evairon,start_response):

# 第一个参数返回状态码,第二个以键值的方式返回你想添加的head部分

start_response('200 ok',[('Content-Type','text/html;charset=utf-8')])

# 返回给网页的内容

try:

file_name = evairon['path_info']

for url,func in URL_FUNC_DICT.items():

# 匹配是否有这个函数,有返回回去

ret = re.match(url,file_name)

if ret:

return func(ret)

except Exception as e:

return '未找到文件 %s'%e

添加delete方法,并匹配所有url为/delete/xxx.html格式的都执行该方法。

@url_func(r'/delete/(\d+)\.html')

def delete(ret):

return '删除方法。ok'

由于给所有函数传递了一个url,所以需要给上面的函数都添加一个参数。

执行:成功返回删除方法。ok,那我们继续完善删除方法。

@url_func(r'/delete/(\d+)\.html')

def delete(ret):

# 获取id值

id = ret.group(1)

# 执行sql删除

conn = connect(host='localhost',port=3306,user='root',password='123456',database='student',charset='utf8')

cursor = conn.cursor()

count = cursor.execute("delete from studentinfo where studentid = %s",(id,))

if count:

conn.commit()

cursor.close()

conn.close()

return '删除成功。ok!!'

else:

return '删除失败!'

其他修改啊,添加,只是sql语句不同,都大同小异。

不过在修改的时候要修改正则,传给数据的还要有修改值没有了解post请求就换个正则匹配

比如127.0.0.1/修改方法/要修改的id/要修改的内容.html,用正则匹配出id和要修改的内容就可以了。

但是有个问题,当我们传递的内容或者汉子的时候会出现乱码,因为是通过url传递的,中途会有个url编码的过程,

我们需要解码:

1、需要导入模块

import urllib

解码:urllib.parse.unquote()

编码:urllib.parse.quote()

添加日志模块

不会日志模块需要看基础:python常用模块二

导入日志模块:import logging

修改application方法:

def application(evairon,start_response):

# 第一个参数返回状态码,第二个以键值的方式返回你想添加的head部分

start_response('200 ok',[('Content-Type','text/html;charset=utf-8')])

file_name = evairon['path_info']

# 写入日志

logging.basicConfig(level=logging.INFO,

filename = './log.txt',

filemode = 'a',

format = '%(asctime)s - %(filename)s[line:%(lineno)d]-%(levelname)s:%(message)s'

)

logging.info('访问了%s'%file_name)

# 返回给网页的内容

try:

for url,func in URL_FUNC_DICT.items():

# 匹配是否有这个函数,有返回回去

ret = re.match(url,file_name)

if ret:

return func(ret)

except Exception as e:

logging.WARNING('找不到文件')

return '未找到文件 %s'%e

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-12-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 python入门到放弃 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档