目录

1.WSGI接口

2.新建WSGI服务器

3.使用if管理请求路径

4.使用字典管理请求路径

5.使用装饰器管理请求路径

6.requests模块的介绍

演示代码:

import re

import socket

from multiprocessing import Process

class WSGIServer():

def __init__(self, server, port, root):

self.server = server

self.port = port

self.root = root

self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

self.server_socket.bind((self.server, self.port))

self.server_socket.listen(128)

def handle_socket(self, socket):

data = socket.recv(1024).decode('utf-8').splitlines()[0]

file_name = re.match(r'[^/]+(/[^ ]*)', data)[1]

# print(file_name)

if file_name == '/':

file_name = self.root + '/index.html'

else:

file_name = self.root + file_name

try:

file = open(file_name, 'rb')

except IOError:

response_header = 'HTTP/1.1 404 NOT FOUND \r\n'

response_header += '\r\n'

response_body = '========Sorry,file not found======='.encode('utf-8')

else:

response_header = 'HTTP/1.1 200 OK \r\n'

response_header += '\r\n'

response_body = file.read()

finally:

socket.send(response_header.encode('utf-8'))

socket.send(response_body)

def forever_run(self):

while True:

client_socket, client_addr = self.server_socket.accept()

# self.handle_socket(client_socket)

p = Process(target=self.handle_socket, args=(client_socket,))

p.start()

client_socket.close()

if __name__ == '__main__':

ip = '0.0.0.0'

port = 8899

server = WSGIServer(ip, port, './pages')

print('server is running at {}:{}'.format(ip, port))

server.forever_run()

1.WSGI接口

WSGI接口定义非常简单,它只要求Web开发者实现一个函数,就可以响应HTTP请求。我们来看一个最简单的Web版本的“Hello, web!”:

def application(environ, start_response):

start_response('200 OK', [('Content-Type', 'text/html')])

return '

Hello, web!

'

上面的application()函数就是符合WSGI标准的一个HTTP处理函数,它接收两个参数:

environ:一个包含所有HTTP请求信息的dict对象; start_response:一个发送HTTP响应的函数。

在application()函数中,调用:

start_response('200 OK', [('Content-Type', 'text/html')])

就发送了HTTP响应的Header,注意Header只能发送一次,也就是只能调用一次start_response()函数。start_response()函数接收两个参数,一个是HTTP响应码,一个是一组list表示的HTTP Header,每个Header用一个包含两个str的tuple表示。

通常情况下,都应该把Content-Type头发送给浏览器。其他很多常用的HTTP Header也应该发送。

然后,函数的返回值'

Hello, web!

'将作为HTTP响应的Body发送给浏览器。

有了WSGI,我们关心的就是如何从environ这个dict对象拿到HTTP请求信息,然后构造HTML,通过start_response()发送Header,最后返回Body。

整个application()函数本身没有涉及到任何解析HTTP的部分,也就是说,底层代码不需要我们自己编写,我们只负责在更高层次上考虑如何响应请求就可以了。

不过,等等,这个application()函数怎么调用?如果我们自己调用,两个参数environ和start_response我们没法提供,返回的str也没法发给浏览器。

所以application()函数必须由WSGI服务器来调用。有很多符合WSGI规范的服务器,我们可以挑选一个来用。但是现在,我们只想尽快测试一下我们编写的application()函数真的可以把HTML输出到浏览器,所以,要赶紧找一个最简单的WSGI服务器,把我们的Web应用程序跑起来。

好消息是Python内置了一个WSGI服务器,这个模块叫wsgiref,它是用纯Python编写的WSGI服务器的参考实现。所谓“参考实现”是指该实现完全符合WSGI标准,但是不考虑任何运行效率,仅供开发和测试使用。

2.新建WSGI服务器

创建hello.py文件,用来实现WSGI应用的处理函数。 def application(environ, start_response):

start_response('200 OK', [('Content-Type', 'text/html')])

print(environ)

return ['

Hello, web!

'.encode('utf-8'),'hello'.encode('utf-8')] 创建server.py文件,用来启动WSGI服务器,加载appliction 函数 # 从wsgiref模块导入:

from wsgiref.simple_server import make_server

# 导入我们自己编写的application函数:

from hello import application

# 创建一个服务器,IP地址为空,端口是8000,处理函数是application:

httpd = make_server('', 8000, application)

print("Serving HTTP on port 8000...")

# 开始监听HTTP请求:

httpd.serve_forever()

3.使用if管理请求路径

文件结构:

├── server.py

 ├── utils.py

 ├── pages

         └── index.html

 └── templates

     └── info.html

utlis.py文件

PAGE_ROOT = './pages'

TEMPLATE_ROOT = './templates'

def load_html(file_name, start_response, root=PAGE_ROOT):

"""

加载HTML文件时调用的方法

:param file_name: 需要加载的HTML文件

:param start_response: 函数,用来设置响应头。如果找到文件,请求头设置为200,否则设置为410

:param root: HTML文件所在的目录。默认PAGE_ROOT表示静态HTML文件,TEMPLATE_ROOT表示的是模板文件

:return: 读取HTML文件成功的话,返回HTML文件内容;读取失败提示资源被删除

"""

file_name = root + file_name

try:

file = open(file_name, 'rb')

except IOError:

start_response('410 GONE', [('Content-Type', "text/html;charset=utf-8")])

return ['资源被删除了'.encode('utf-8')]

else:

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

content = file.read()

return [content]

def load_template(file_name, start_respone, **kwargs):

"""

加载模板文件

:param file_name: 需要加载的模板文件名

:param start_respone: 函数,用来设置响应头。如果找到文件,请求头设置为200,否则设置为410

:param kwargs: 用来设置模板里的变量

:return: 读取HTML文件成功的话,返回HTML文件内容;读取失败提示资源被删除

"""

content = load_html(file_name, start_respone, root=TEMPLATE_ROOT)

html = content[0].decode('utf-8')

if html.startswith(''):

return [html.format(**kwargs).encode('utf-8')]

else:

return content

service.py文件

from wsgiref.simple_server import make_server

from utils import load_html, load_template

def show_home(start_response):

return load_html('/index.html', start_response)

def show_test(start_response):

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

return ['我是一段普通的文字'.encode('utf-8')]

def show_info(start_response):

return load_template('/info.html', start_response, name='张三',age=18})

def application(environ, start_response):

path = environ.get('PATH_INFO')

# 处理首页请求(加载一个HTML文件)

if path == '/' or path == '/index.html':

result = show_home(start_response)

return result

# 处理test.html请求(返回一个普通的字符串)

elif path == '/test.html':

return show_test(start_response)

# 处理info.html请求(加载一个模板并且返回)

elif path == '/info.html':

return show_info(start_response)

# 其它请求暂时无法处理,返回404

else:

start_response('400 NOT FOUND', [('Content-Type', "text/html;charset=utf-8")])

return ['页面未找到'.encode('utf-8')]

httpd = make_server('', 8000, application)

print("Serving HTTP on port 8000...")

httpd.serve_forever()

4.使用字典管理请求路径

文件结构:

 ├── server.py

 ├── utils.py

 ├── urls.py

 ├── pages

         └── index.html

 └── templates

     └── info.html

urls.py文件:该文件里只有一个字典对象,用来保存请求路径和处理函数之间的对应关系。

urls = {

'/': 'show_home',

'/index.html': 'show_home',

'/test.html': 'show_test',

'/info.html': 'show_info'

}

server.py文件:

from wsgiref.simple_server import make_server

from urls import urls

from utils import load_html, load_template

def show_home(start_response):

return load_html('/index.html', start_response)

def show_test(start_response):

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

return ['我是一段普通的文字'.encode('utf-8')]

def show_info(start_response):

return load_template('/info.html', start_response, name='张三',age=18})

def application(environ, start_response):

path = environ.get('PATH_INFO')

# 这里不再是一大堆的if...elif语句了,而是从urls字典里获取到对应的函数

func = urls.get(path)

if func:

return eval(func)(start_response)

# 其它请求暂时无法处理,返回404

else:

start_response('400 NOT FOUND', [('Content-Type', "text/html;charset=utf-8")])

return ['页面未找到'.encode('utf-8')]

httpd = make_server('', 8000, application)

print("Serving HTTP on port 8000...")

httpd.serve_forever()

5.使用装饰器管理请求路径

from wsgiref.simple_server import make_server

from utils import load_html, load_template

g_url_route = {}

def route(url):

def handle_action(action):

g_url_route[url] = action

def do_action(start_response):

return action(start_response)

return do_action

return handle_action

@route('/index.html')

@route('/')

def show_home(start_response):

return load_html('/index.html', start_response)

@route('/test.html')

def show_test(start_response):

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

return ['我是一段普通的文字'.encode('utf-8')]

@route('/info.html')

def show_info(start_response):

return load_template('/info.html', start_response, name='张三', age=18)

def application(environ, start_response):

file_name = environ.get('PATH_INFO')

try:

return g_url_route[file_name](start_response)

except Exception:

start_response('404 NOT FOUND', [('Content-Type', 'text/html;charset=utf-8')])

return ['对不起,界面未找到'.encode('utf-8')]

if __name__ == '__main__':

httpd = make_server('', 8000, application)

print("Serving HTTP on port 8000...")

httpd.serve_forever()

6.requests模块的介绍

除了使用浏览器给服务器发送请求以外,我们还可以使用第三方模块requests用代码来给服务器发送器请求,并获取结果。

url = 'https://www.apiopen.top/satinApi'

params = {'type': 1, 'page': 2}

response = requests.get(url, params)

print(response)

# 方法二: 只能用于get请求

url = 'https://www.apiopen.top/satinApi?type=1&page=1'

response = requests.get(url)

# print(response)

# 2.获取请求结果

print(response.headers)

# 2)响应体(数据)

# a.获取二进制对应的原数据(数据本身是图片、压缩文件、视频等文件数据)

content = response.content

print(type(content))

# b.获取字符类型的数据

text = response.text

print(type(text))

# c.获取json数据(json转换成python对应的数据)

json = response.json()

print(type(json))

print(json)

相关链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: