当前位置:
首页 > Python基础教程 >
-
python asyncio aiohttp 异步下载 完整例子
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/dashoumeixi/article/details/81085141
asyncio 基础:python asyncio 协程
之前完整的说明了并发下载例子: 并发下载
使用了aiohttp,
注意, 下面写文件没有使用异步写入.一般情况下可以配合ThreadPoolExecutor来结合写入文件 : 关于aiohttp下载大文件的方式
import os,sys,time,asyncio,aiohttp
import tqdm
FLAGS = ('CN IN US ID BR PK NG BD RU JP '
'MX PH VN ET EG DE IR TR CD FR').split()
BASE_URL = 'http://flupy.org/data/flags' #下载url
DEST_DIR = 'downloads/' #保存目录
#获取链接,下载文件
async def fetch(session:aiohttp.ClientSession,url:str,path:str,flag:str):
print(flag, ' 开始下载')
async with session.get(url) as resp:
with open(path,'wb') as fd:
while 1:
chunk = await resp.content.read(1024) #每次获取1024字节
if not chunk:
break
fd.write(chunk)
return flag
async def begin_download(sem,session:aiohttp.ClientSession,url:str,path:str,flag:str):
#控制协程并发数量
with (await sem):
return await fetch(session,url,path,flag)
async def download(sem:asyncio.Semaphore):
tasks = []
async with aiohttp.ClientSession() as session:
for flag in FLAGS:
#创建路径以及url
path = os.path.join(DEST_DIR, flag.lower() + '.gif')
url = '{}/{cc}/{cc}.gif'.format(BASE_URL, cc=flag.lower())
#构造一个协程列表
tasks.append(asyncio.ensure_future(begin_download(sem,session, url, path, flag)))
#等待返回结果
tasks_iter = asyncio.as_completed(tasks)
#创建一个进度条
fk_task_iter = tqdm.tqdm(tasks_iter,total=len(FLAGS))
for coroutine in fk_task_iter:
#获取结果
res = await coroutine
print(res, '下载完成')
#创建目录
os.makedirs(DEST_DIR,exist_ok=True)
#获取事件循环
lp = asyncio.get_event_loop()
start = time.time()
#创建一个信号量以防止DDos
sem = asyncio.Semaphore(4)
lp.run_until_complete(download(sem))
end = time.time()
lp.close()
print('耗时:',end-start)
在写文件那块代码可以使用 run_in_executor 这个函数执行,事件循环中包含一个默认的线程池(ThreadPoolExecutor).
run_in_executor(executor, func, *args) 原型 . executor == None, 使用默认的. 可以自己创建一个;
具体代码:
#线程运行的函数
def save_file(fd:io.BufferedWriter,chunk):
fd.write(chunk)
#获取链接,下载文件
async def fetch(session:aiohttp.ClientSession,url:str,path:str,flag:str):
print(flag, ' 开始下载')
async with session.get(url) as resp:
with open(path,'wb') as fd:
while 1:
chunk = await resp.content.read(8192)
if not chunk:
break
lp = asyncio.get_event_loop()
lp.run_in_executor(None,save_file,fd,chunk)
# fd.write(chunk)
return flag
————————————————
版权声明:本文为CSDN博主「dashoumeixi」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/dashoumeixi/article/details/81085141
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比
一款纯 JS 实现的轻量化图片编辑器
关于开发 VS Code 插件遇到的 workbench.scm.
前端设计模式——观察者模式
前端设计模式——中介者模式
创建型-原型模式