Python使用aiohttp异步请求模块实现简单的服务接口
aiohttp可以理解成是和requests对应Python异步网络请求库,它是基于 asyncio 的异步模块,可用于实现异步爬虫,有点就是更快于 requests 的同步爬虫。
安装方式:pip install aiohttp
aiohttp是一个为Python提供异步HTTP 客户端/服务端编程,基于asyncio(Python用于支持异步编程的标准库)的异步库。asyncio可以实现单线程并发IO操作,
其实现了TCP、UDP、SSL等协议,aiohttp就是基于asyncio实现的http框架。
1.实现请求类:
#!/usr/bin/python3
import asyncio
from aiohttp import web
import json
class testAPI():
HTTP_IP = '0.0.0.0' # 注意替换成内网IP
HTTP_PORT = 8888 # 可随意修改
# 单例模式 单例模式可以保证一个类仅有一个实例,并提供一个访问它的全局访问点。适用性于当类只能有一个实例而且客户可以从一个众所周知的访问点访问它,
例如访问数据库、MQ等
def __new__(cls, *args, **kwargs):
if not hasattr(cls, '_instance'):
cls._instance = object.__new__(cls)
return cls._instance
def __int__(self):
pass
2.注册路径与请求:
async def req(self, request): # 创建请求处理程序
result = {}
print('===>main.')
print(request.match_info)
await asyncio.sleep(0.01) # 假装去处理事情
if request.method == 'GET':
result['http_method'] = 'GET'
req_data = request.rel_url.query
elif request.method == 'POST':
result['http_method'] = 'POST'
req_data = await request.post()
# 创建一个空字典
params = {}
for key in req_data:
params[key] = req_data[key]
result['stat'] = 1
result['params'] = params
result['req_url'] = str(request.rel_url)
result['req_url_len'] = len(str(request.rel_url))
return web.Response(body=json.dumps(result), content_type='application/json') # application/json
async def index(self, request):
return web.Response(body='<h1>Index hello,world</h1>'.encode(), content_type='application/json')
# async
# 协程函数:定义函数时加上async修饰,即async def func()
# 协程对象:执行协程函数得到的对象
# 注:执行协程函数得到协程对象,函数内部代码不会执行
async def init(self, loop):
app = web.Application() # 创建application实例
# 定义接口方法(即请求处理函数),该方法接收一个参数request.类型为: aiohttp.web_request.Request
app.router.add_route('GET', '/', self.index) # 注册路径与请求处理程序
app.router.add_route('GET', '/req', self.req) # 之所以上面能识别name,就是因为在这里定义的。
app.router.add_route('POST', '/req', self.req) # 之所以上面能识别name,就是因为在这里定义的。
# 如果想要使该接口即支持post请求也支持get请求,app.router.add_route("*", "/path")
# await + 可等待对象(协程对象,Future,Task对象(IO等待))
# 等待到对象的返回结果,才会继续执行后续代码
srv = await loop.create_server(app._make_handler(), self.HTTP_IP, self.HTTP_PORT)
print('server started at http://%s:%d...' % (self.HTTP_IP, self.HTTP_PORT))
return srv
3.启动服务:
api = testAPI()
# 创建事件循环
loop = asyncio.get_event_loop()
# 添加任务,直至所有任务执行完成
loop.run_until_complete(api.init(loop))
# 无限运行事件循环。直至loop.stop停止
loop.run_forever()
# asyncio事件循环(python3.6)
# 事件循环:去检索一个任务列表的所有任务,并执行所有未执行任务,直至所有任务执行完成。
# 执行协程函数,必须使用事件循环。
4.请求结果:
进击的qing