Tornado异步模式
先介绍下背景:由于工作需要,前段时间又写了一段爬虫去获取和更新一些数据。之前爬虫主要用scrapy框架批量爬取一些页面数据,或者用gevent调用目标站点的接口。偶然看到了tornado,听说这个框架很强大,所以打算这次爬虫用tornado试试。不足之处,欢迎指正。
总的来说,tornado是python里面一个轻量的异步非阻塞的框架,性能非常不错,最新版本的异步协程是基于python内置的asyncio来实现(老版本用装饰器实现异步)。tornado可以用来做web服务,或者利用其异步功能,完成一些异步执行的操作,比如爬虫(pyspider就是基于tornado实现)。
本次任务,涉及到调用百度自然语言理解(nlu)平台unit的一些接口,实现一些自动化和批量操作,比如词槽导入导出,开始机器学习训练,批量测试语句等等。没有拿到百度unit平台的接口文档,所以只能通过爬虫形式,模拟用户登录,然后进行各种操作。为了让本篇看起来更简洁,本次不打算详细介绍如何爬取百度unit平台,统一调用httpbin(http://www.httpbin.org/get)进行简化。百度unit平台的爬虫后续再补充。
说了那么多,重点来了。tornado两种异步模式:
1,add_callback(基于asyncio,资源消耗少,性能还不错)
2,run_in_executor((基于线程池/进程池,性能很好,但是资源消耗要高于add_callback的方案)
add_callback方案:
from tornado.ioloop import ioloop, periodiccallback import requests # 业务逻辑操作写在这里 def job(): url = 'http://www.httpbin.org/get' resp = requests.get(url) print(resp.text) async def runner(): loop = ioloop.current()
#任务派发写在这里 for i in range(10): loop.add_callback(job) print('this will be executed before loop is finished') if __name__ == '__main__': ioloop.current().run_sync(runner)
run_in_executor方案:
from tornado.ioloop import ioloop, periodiccallback import requests from concurrent.futures import threadpoolexecutor # 业务逻辑写在这里 def job(): url = 'http://www.httpbin.org/get' resp = requests.get(url) print(resp.text) async def runner(): loop = ioloop.current() # 也可以用进程池processpoolexecutor exectutor = threadpoolexecutor(20)
# 任务派发写在这里 for i in range(10): loop.run_in_executor(exectutor, job) print('this will be executed before loop is finished') if __name__ == '__main__': ioloop.current().run_sync(runner)
上一篇: 小程序组件之仿微信通讯录的实现代码
下一篇: day13-生成器