elk-min.jpg

博客系统使用 Flask 开发,ORM使用 MongoEngine,文章正文支持Markdown。使用上一篇文章中搭建的 Elasticsearch 来实现博文全文检查,需要使用 Python Elasticsearch Client 来操作 Elasticsearch。为各个数据模型创建Index,添加对象时自动往对应的Index中添加Document,删除对象时自动删除Document,这就要用到 mongoengine.signals 所提供的 "信号" 机制。高亮搜索词使用 re 正则表达式,难点在于文章正文是 Markdown 类型的,所以可能会出现搜索词刚好在 图片链接、URL链接、TOC目录的锚中,需要额外处理

elk-min.jpg

Elasticsearch 是一个分布式的 RESTful 风格的搜索和数据分析引擎,能够解决不断涌现出的各种用例。作为 Elastic Stack 的核心,它集中存储您的数据(结构化、非结构化、地理位置、度量指标),帮助您发现意料之中以及意料之外的情况。无论 Elasticsearch 是在一个节点上运行,还是在一个包含 300 个节点的集群上运行,您都能够以相同的方式与 Elasticsearch 进行通信。 它能够水平扩展,每秒钟可处理海量事件,同时能够自动管理索引和查询在集群中的分布方式,以实现极其流畅的操作

spider 11-min.png

爬取 www.mzitu.com 全站图片,截至目前共4725个图集,14.5万多张美女图片,使用 asyncio 和 aiohttp 实现的异步版本只需要不到2小时就能爬取完成。按日期创建图集目录,保存更合理。控制台只显示下载的进度条,详细信息保存在日志文件中。支持异常处理,不会终止爬虫程序。失败的请求,下次再执行爬虫程序时会自动下载

spider 09-min.jpg

支持HTTP协议的异步网络I/O库:aiohttp,我们的爬虫需要使用该库的Client功能。需要结合asyncio一起使用,经过测试,单线程的异步编程比多线程版本的性能还要好一些,毕竟没有创建线程的开销和线程间上下文切换。另外,如果你下载的是视频等大文件,此时,将网络数据保存到本地磁盘的这个过程,本身是阻塞的,所以它会阻塞事件循环。asyncio不支持磁盘I/O异步,需要使用aiofiles,其实它背后也只是创建一个线程池而已。后续爬虫实战时,动辄下载数十万个文件,为保持控制台清爽,需要使用 progressbar2 显示进度条,而详细信息将保存到日志文件中