比起上两篇文章来说,这篇相对比较简单。
在实际中,经常需要创建后台运行的任务,用于定时更新或者其他事情。
例如,之前写过一些爬虫的文章,在存储到数据库时,可以考虑写成把要存储的数据再通过requests等,post到服务器的方式,让views.py的某个视图函数统一插入数据库。
这时,要避免爬取重复新闻,就可以通过判断url的方式,于是需要后台任务定时重新获取某个范围内(如两天内)的url存储到app['old_urls'],再在views.py的视图函数中每次插入时也添加到app['old_urls']。
只要思路清楚,上面这段话在看完这篇文章后应该能很容易的实现出来。
这篇文章只讲一个非常简单的例子,获取2000条最新的url:
定时更新只需要用while True就行了,然后sleep的时间间隔采用之前在config设定好的update_interval。
于是,应该在db.py中添加如下代码:
注意for循环中的解包写法,如果有疑惑,建议sql中多select一个id等字段,for _, url in来写看起来就很直观了。
最后把结果存储到app['old_urls']中。
再把这个任务添加到启动和清理的任务列表中:
注意这里事件循环loop是app的属性。
清理需要先cancel,再等待。
最后,再在main.py中给app启动和关闭时的任务列表添加这些:
app.on_startup.append(start_background_tasks)
app.on_cleanup.append(cleanup_background_tasks)
这样,就创建好了后台任务。
在views.py中,通过request.app['old_urls']可以访问后台获取的url。
例如:
运行python main.py后,在http://127.0.0.1/test可以看到结果中前100条url。
改写
上篇文章介绍了aiohttp怎么保证清理任务只在成功初始化时运行,我们的后台任务也可以这样改写:
于是,可以把刚刚添加的2行app.on_startup/app.on_cleanup代码删掉,再添加1行:
app.cleanup_ctx.append(background_tasks)
对比一下应该很容易就能写出来,如果有疑惑建议重看上一篇文章。
这篇文章的全部代码可以从https://github.com/lucays/toutiao/tree/master/17获取。
仍然要记得把conf.json中mysql配置的省略号换成自己mysql数据库的配置。