前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python 模块 aiohttp

Python 模块 aiohttp

作者头像
不可言诉的深渊
发布2020-02-26 14:21:36
6470
发布2020-02-26 14:21:36
举报
文章被收录于专栏:Python机器学习算法说书人
上次进行网站检测的时候说到如果网站太多检测太慢怎么办,这个问题解决方法有很多种,比如多线程、多进程、异步 IO,我们首先看一下这三者的区别。

概述

首先我们看一下多进程、多线程、异步 IO,三者的区别。多进程顾名思义就是多个进程处理任务,多线程顾名思义就是多个线程处理任务,不管是多线程还是多进程,设置多少个线程或者进程是一个大难题!多了,系统资源消耗过高;少了,并发性就不够了。那么,有没有什么办法可以减少大量进程或者线程的创建产生的大量内存占用?其实是有的,就是利用所谓的线程池或者进程池;既然减少了创建和销毁对象产生的开销,那么进程或者线程切换的开销有没有办法减少呢?其实是有的,我们直接使用异步 IO 就可以了,异步 IO 实际上是异步非阻塞 IO,就是让保证一个线程或者进程在当前的 IO 请求还未完成的时候去执行其他任务,既不需要申请大量的系统资源,也不会产生阻塞,因此异步 IO 成了加快检测速度的首选。

仅仅知道这些停留在理论还不够,我们还需要知道 Python 的异步 IO 相关模块,这样的模块非常多,比如 aiohttp、gevent……因为我这里是为了加速网站请求,要求一个单位时间内请求大量的网站,所以在这里我选择 aiohttp 这个模块。

同步耗时

我们先来测试一下不使用异步 IO 处理上次讲网站检测的那些网站检测完成需要多久时间,还是上次的代码,我在这里只给出需要修改的代码,首先从 time 模块导入一个名叫 time 的函数(即 from time import time),然后直接在 if __name__ == '__main__' 里面改成如下所示就行了:

代码语言:javascript
复制
 if __name__ == '__main__':
     start = time()
     website_detection = WebsiteDetection()
     website_detection.filter()
     website_detection.detect()
     website_detection.save()
     print(time()-start)

运行结果如图所示。

异步耗时

在讲解异步耗时之前,我们首先需要把代码中的 detect 方法改成异步,这太简单了,直接给出修改后的完整代码。

代码语言:javascript
复制
 from asyncio import get_event_loop
 from time import time
 from aiohttp import ClientSession
 from redis.client import Redis
 
 
 class WebsiteDetection:
     def __init__(self):
         self.websites = open('websites.txt').readlines()
         self.status_code_score = {'5': 0, '4': 1, '3': 2, '2': 3}
         self.website_score = {}
 
     async def detect(self):
         async with ClientSession(headers={
             'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239'
                           '.132 Safari/537.36 QIHU 360SE'})as session:
             for website in self.websites:
                 print(website)
                 async with session.get(website)as response:
                     self.website_score[website] = self.status_code_score[str(response.status)[0]]
 
     def filter(self):
         self.websites = {'/'.join(website.strip('\n').split('/', maxsplit=3)[:-1])+'/'for website in self.websites}
 
     def save(self):
         redis = Redis()
         for website, score in self.website_score.items():
             redis.zadd('websites', website, score)
         redis.connection_pool.disconnect()
 
 
 if __name__ == '__main__':
     start = time()
     website_detection = WebsiteDetection()
     website_detection.filter()
     get_event_loop().run_until_complete(website_detection.detect())
     website_detection.save()
     print(time()-start)

运行结果如图所示。

和同步相比差了没多少,但是确实可以发现异步的效率要比同步高,为什么这里差了没多少主要是因为网站数量太少了,异步和同步并没什么太大的区别,如果有几千个甚至几万个网站可能差距就出来了。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-02-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python机器学习算法说书人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档