游戏电视苹果数码历史美丽
投稿投诉
美丽时装
彩妆资讯
历史明星
乐活安卓
数码常识
驾车健康
苹果问答
网络发型
电视车载
室内电影
游戏科学
音乐整形

Python协程asyncio极简入门与爬虫实战

  作者:读者投稿
  来源:早起Python
  在了解了Python并发编程的多线程和多进程之后,我们来了解一下基于asyncio的异步IO编程协程01、协程简介
  协程(Coroutine)又称微线程、纤程,协程不是进程或线程,其执行过程类似于Python函数调用,Python的asyncio模块实现的异步IO编程框架中,协程是对使用async关键字定义的异步函数的调用;
  一个进程包含多个线程,类似于一个人体组织有多种细胞在工作,同样,一个程序可以包含多个协程。多个线程相对独立,线程的切换受系统控制。同样,多个协程也相对独立,但是其切换由程序自己控制。02、一个简单例子
  我们来使用一个简单的例子了解协程,首先看看下面的代码:importtimedefdisplay(num):time。sleep(1)print(num)fornuminrange(10):display(num)
  很容易看得懂,程序会输出0到9的数字,每隔1秒中输出一个数字,因此整个程序的执行需要大约10秒时间。值得注意的是,因为没有使用多线程或多进程(并发),程序中只有一个执行单元(只有一个线程在执行),而time。sleep(1)的休眠操作会让整个线程停滞1秒钟,
  对于上面的代码来说,在这段时间里面CPU是闲置的没有做什么事情。
  我们再来看看使用协程会发生什么:importasyncioasyncdefdisplay(num):在函数前使用async关键字,变成异步函数awaitasyncio。sleep(1)print(num)
  异步函数不同于普通函数,调用普通函数会得到返回值,而调用异步函数会得到一个协程对象。我们需要将协程对象放到一个事件循环中才能达到与其他协程对象协作的效果,因为事件循环会负责处理子程序切换的操作。
  简单的说就是让阻塞的子程序让出CPU给可以执行的子程序。
  03、基本概念
  异步IO是指程序发起一个IO操作(阻塞等待)后,不用等IO操作结束,可以继续其它操作;做其他事情,当IO操作结束时,会得到通知,然后继续执行。异步IO编程是实现并发的一种方式,适用于IO密集型任务
  Python模块asyncio提供了一个异步编程框架,全局的流程图大致如下:
  下面对每个函数都从代码层面进行介绍
  async:定义一个方法(函数),这个方法在后面的调用中不会被立即执行而是返回一个协程对象;asyncdeftest():print(hello异步)test()调用异步函数输出:RuntimeWarning:coroutinetestwasneverawaited
  coroutine:协程对象,也可以将协程对象添加到时间循环中,它会被事件循环调用;asyncdeftest():print(hello异步)ctest()调用异步函数,得到协程对象cprint(c)输出:coroutineobjecttestat0x0000023FD05AA360
  eventloop:事件循环,相当于一个无限循环,可以把一些函数添加到这个事件中,函数不会立即执行,而是满足某些条件的时候,函数就会被循环执行;asyncdeftest():print(hello异步)ctest()调用异步函数,得到协程对象cloopasyncio。geteventloop()创建事件循环loop。rununtilcomplete(c)把协程对象丢给循环,并执行异步函数内部代码输出:hello异步
  await:用来挂起阻塞方法的执行;importasynciodefrunning1():asyncdeftest1():print(1)awaittest2()print(2)asyncdeftest2():print(3)print(4)loopasyncio。geteventloop()loop。rununtilcomplete(test1())ifnamemain:running1()
  输出:
  task:任务,对协程对象的进一步封装,包含任务的各个状态;asyncdeftest():print(hello异步)ctest()调用异步函数,得到协程对象cloopasyncio。geteventloop()创建事件循环taskloop。createtask(c)创建task任务print(task)loop。rununtilcomplete(task)执行任务输出:Taskpendingcorotest()runningatD:xxxx。pytaskhello异步异步函数内部代码一样执行
  future:代表以后执行或者没有执行的任务,实际上和task没有本质区别;这里就不做代码展示;
  首先使用一般方式方法创建一个函数:deffunc(url):print(f正在对{url}发起请求:)print(f请求{url}成功!)func(www。baidu。com)
  结果如下所示:正在对www。baidu。com发起请求:请求www。baidu。com成功04、基本操作
  创建协程对象
  通过async关键字定义一个异步函数,调用异步函数返回一个协程对象。
  异步函数就是在函数执行过程中挂起,去执行其他异步函数,等待挂起条件(time。sleep(n))消失后,再回来执行,接着我们来修改上述代码:asyncdeffunc(url):print(f正在对{url}发起请求:)print(f请求{url}成功!)func(www。baidu。com)
  结果如下:RuntimeWarning:coroutinefuncwasneverawaited
  这就是之前提到的,使用async关键字使得函数调用得到了一个协程对象,协程不能直接运行,需要把协程加入到事件循环中,由后者在适当的时候调用协程;
  创建task任务对象
  task任务对象是对协程对象的进一步封装;importasyncioasyncdeffunc(url):print(f正在对{url}发起请求:)print(f请求{url}成功!)cfunc(www。baidu。com)函数调用的写成对象cloopasyncio。geteventloop()创建一个时间循环对象taskloop。createtask(c)loop。rununtilcomplete(task)注册加启动print(task)
  结果如下:正在对www。baidu。com发起请求:请求www。baidu。com成功!Taskfinishedcorofunc()done,definedatD:datatest。py:10resultNone
  future的使用
  前面我们提及到future和task没有本质区别asyncdeffunc(url):print(f正在对{url}发起请求:)print(f请求{url}成功!)cfunc(www。baidu。com)函数调用的写成对象cloopasyncio。geteventloop()创建一个时间循环对象futuretaskasyncio。ensurefuture(c)print(futuretask,未执行)loop。rununtilcomplete(futuretask)注册加启动print(futuretask,执行完了)
  结果如下:Taskpendingcorofunc()runningatD:datatest。py:10未执行正在对www。baidu。com发起请求:请求www。baidu。com成功!Taskfinishedcorofunc()done,definedatD:datatest。py:10resultNone执行完了
  await关键字的使用
  在异步函数中,可以使用await关键字,针对耗时的操作(例如网络请求、文件读取等IO操作)进行挂起,比如异步程序执行到某一步时需要很长时间的等待,就将此挂起,去执行其他异步函数importasyncio,timeasyncdefdosomework(n):使用async关键字定义异步函数print(等待:{}秒。format(n))awaitasyncio。sleep(n)休眠一段时间return{}秒后返回结束运行。format(n)starttimetime。time()开始时间corodosomework(2)loopasyncio。geteventloop()创建事件循环对象loop。rununtilcomplete(coro)print(运行时间:,time。time()starttime)
  运行结果如下:等待:2秒运行时间:2。00131201744079605、多任务协程
  任务(Task)对象用于封装协程对象,保存了协程运行后的状态,使用rununtilcomplete()方法将任务注册到事件循环;
  如果我们想要使用多任务,那么我们就需要同时注册多个任务的列表,可以使用rununtilcomplete(asyncio。wait(tasks)),
  这里的tasks,表示一个任务序列(通常为列表)
  注册多个任务也可以使用rununtilcomplete(asyncio。gather(tasks))importasyncio,timeasyncdefdosomework(i,n):使用async关键字定义异步函数print(任务{}等待:{}秒。format(i,n))awaitasyncio。sleep(n)休眠一段时间return任务{}在{}秒后返回结束运行。format(i,n)starttimetime。time()开始时间tasks〔asyncio。ensurefuture(dosomework(1,2)),asyncio。ensurefuture(dosomework(2,1)),asyncio。ensurefuture(dosomework(3,3))〕loopasyncio。geteventloop()loop。rununtilcomplete(asyncio。wait(tasks))fortaskintasks:print(任务执行结果:,task。result())print(运行时间:,time。time()starttime)
  运行结果如下:任务1等待:2秒任务2等待:1秒任务3等待:3秒任务执行结果:任务1在2秒后返回结束运行任务执行结果:任务2在1秒后返回结束运行任务执行结果:任务3在3秒后返回结束运行运行时间:3。002867698669433606、实战爬取LOL皮肤
  首先打开官网:
  可以看到英雄列表,这里就不详细展示了,我们知道一个英雄有多个皮肤,我们的目标就是爬取每个英雄的所有皮肤,保存到对应的文件夹里;
  打开一个英雄的皮肤页面,如下所示:
  黑暗之女,下面的小兔对应的就是该隐兄弟皮肤,然后通过查看network发现对应的皮肤数据在js文件里;
  然后我们发现了英雄皮肤存放的url链接规律:url1https:game。gtimg。cnimageslolactimgjshero1。jsurl2https:game。gtimg。cnimageslolactimgjshero2。jsurl3https:game。gtimg。cnimageslolactimgjshero3。js
  我们发现只有id参数是动态构造的,规律是:https:game。gtimg。cnimageslolactimgjshero{}。js。format(i)
  但是这个id只有前面的是按顺序的,在展示全部英雄的页面找到对应英雄的id,
  这里截取的是最后几个英雄的id,所以要全部爬取,需要先设置好id,由于前面的是按顺序的,这里我们就爬取前20个英雄的皮肤;
  1。获取英雄皮肤ulr地址:
  前面的英雄id是按顺序的所有可以使用range(1,21),动态构造url;defgetpage():pageurls〔〕foriinrange(1,21):urlhttps:game。gtimg。cnimageslolactimgjshero{}。js。format(i)print(url)pageurls。append(url)returnpageurls
  2。请求每一页的url地址
  并对网页进行解析获取皮肤图片的url地址:defgetimg():imgurls〔〕pageurlsgetpage()forpageurlinpageurls:resrequests。get(pageurl,headersheaders)resultres。content。decode(utf8)resdictjson。loads(result)skinsresdict〔skins〕forheroinskins:item{}item〔name〕hero〔heroName〕item〔skinname〕hero〔name〕ifhero〔mainImg〕:continueitem〔imgLink〕hero〔mainImg〕print(item)imgurls。append(item)returnimgurls
  说明:resdictjson。loads(result):将得到的json格式字符串转化为字典格式;heroName:英雄名字(这个一定是一样的,方便我们后面根据英雄名创建文件夹);name:表示完整的名字,包括皮肤名(这个一定是不一样的)有的mainImg是空的,我们需要进行一个判断;
  3。创建协程函数
  这里我们根据英雄名创建文件夹,然后就是注意图片的命名,不要忘记,目录结构确立asyncdefsaveimg(index,imgurl):path皮肤imgurl〔name〕ifnotos。path。exists(path):os。makedirs(path)contentrequests。get(imgurl〔imgLink〕,headersheaders)。contentwithopen(。皮肤imgurl〔name〕imgurl〔skinname〕str(index)。jpg,wb)asf:f。write(content)
  主函数:defmain():loopasyncio。geteventloop()imgurlsgetimg()print(len(imgurls))tasks〔saveimg(img〔0〕,img〔1〕)forimginenumerate(imgurls)〕try:loop。rununtilcomplete(asyncio。wait(tasks))finally:loop。close()
  4。程序运行ifnamemain:starttime。time()main()endtime。time()print(endstart)
  运行结果:
  下载233张图花费了42s,可以看到速度还行,文件目录结果如下:
  与requests对比
  异步爬取图片之后,我们有必要使用requests去进行同步数据爬取,进行效率对比,所以在原有代码的基础上进行修改,这里直接略过,思路都是一样的,这是把一部当中的事件循环替换成循环即可:imgurlsgetimg()print(len(imgurls))fori,imgurlinenumerate(imgurls):saveimg(i,imgurl)
  我们可以看到,使用协程的速度要比requests快了一些。
  以上就是本文的全部内容,感兴趣的读者可以自己动手敲一遍代码~

三星GalaxyNote10真机曝光屏占比极高还有全新配色8月1日消息,据悉,三星将于下周正式发布GalaxyNote10系列手机。而在近日,三星GalaxyNote10真机在韩国现身,并配有该机的亮屏照片。下面我们一起来看看该机的具……锐龙95900HX超频版处理器ROG枪神5Plus发布核心卖点:AMD锐龙95900HX超频版处理器、NVIDIAGeForceRTX3070RTX3080显卡130W高性能版本、HyperDrive高速SSD枪神5采用300Hz……Steam掌机来袭,你还会选择Switch吗?7月16日,V社发布了旗下第一款手持PC游戏机,名为SteamDeck,并定在今年12。式上市,不过现在steam上已经开通了预定通道,果真是游戏平台还带预购的。乍看这个外观,……淘宝slogan更新背后也太会玩了吧9月1日下午,太了吧体突然上了热搜。太了吧体究竟是怎么火起来的?这还要从8月30日,淘宝官方微博宣布更换新slogan,在微博上,淘宝不仅官宣新slogan,还开启了与多个品牌……同是装修房子,有人发现百年古画,有人找到诡异娃娃装修房子的时候,似乎总能发现点意料之外的东西。菌菌曾经住过一个有着一个多世纪之久的Airbnb。房东介绍说,当时从房梁间取出了很多用作防寒保暖的报纸,都是六七十年前的。……为什么洗地机那么贵,还能这么火?了解过工作原理你就会明白每当次朋友家,媳妇总会被某些小东西给种草。大件因为价格、占地等因素很难被种草,但这一次真的失败了。那什么东西让人用了就上瘾?家庭主妇一定会推荐洗地机,因为我将这件事儿都全权交给……方法案例9大绩效考核评分方法深度解析(龙头企业考核案例)2020年的大多数企业的关键词是降本增效,如何提升员工效率?如何去评估员工的工作成果,进一步指导人才晋升、调岗工作?绩效考核评分,HR一定要学!绩效考核评分如何不流于形式……华黑们急了!华为鸿蒙os操作系统为套壳安卓?鸿蒙os操作系统到底算不算是安卓套壳?简单来说,目前的鸿蒙2。0可以看作是借助安卓内核的过渡版本。具体算不算?还需要各位去理性看待。从我们的实际使用情况来看:……汽车底盘暗藏危险,这几个位置千万别忽略汽车底盘作为汽车三大件,它出现问题的概率并不低于发动机,我们在日常维护保养汽车时,绝对不能忽视对汽车底盘的检查。如果汽车在行驶的过程中出现了漏油、异常颠簸以及异响,那很有……华为发布鲲鹏云手机,阿里发布无影云电脑,摆脱硬件限制9月17日,2020年阿里云栖大会开幕,本届大会首次线上举办。在本届大会上,阿里第一款云电脑产品无影正式发布!为飞天云这台超级计算机安装了一个原生操作系统,阿里云正式进入……西游记七大圣都去哪了七大圣结交后有没有互相帮助在我国传统四大名著之一西游记中,故事刚开始讲述了孙悟空和其他六个兄弟结拜的故事。孙悟空最后大闹天宫,被如来佛祖压到了五指山下,大哥牛魔王练成了一班武艺,学会72变,接受了上天的……一文解读黑莓BlackBerryKEY35G2021BlackBerryKEY2黑莓手机是手机中一款不可多见的固执型手机,手机的发展已到大屏、超大屏的时代,她却依旧保持着复古的物理按键配备大屏设计,也算是一支奇葩。继……
智能锁保养攻略你知道吗?智能锁保养得好,使用寿命延长两三年完全没问题。不要以为智能锁不需要保养,里面机械部件,使用不当会容易造成损坏的。俗话说,保养是老样子,不保养是样子老。人如此,锁亦然。……全自动洗碗机的优势洗碗机操作简单,易于理解。至于洗碗机洗碗是否够干净,高温水,高达6080度,加上各种各样的高压喷淋冲洗和消毒、烘干,恐怕手洗难以达到吧?自动洗碗机优势:1。节省劳动……Hystrix高级属性配置在几篇的讲解和操作中,我们已经知道了服务与服务之间是通过Hystrix来实现服务熔断与降级的,Hystrix官网上除了介绍Hystrix外,还列出了一些Hystrix高级属性配……风靡游戏中的活化石,大众Type2将出现油电混合动力版?【新车资讯】大吉大利,今晚吃鸡!一款由名不见经传的小公司蓝洞出品的绝地求生游戏,火遍全球!在经过腾讯接手开发了手游版和平精英后,人气更是居高不下。在吃鸡游戏中,载具的运用……为什么有些人对外人很客气,对自己的亲人却很苛刻,这是什么心理怎么说呢,我觉得这其实是一种欺软怕硬的心理。比如,老舍一篇短篇小说里的主人公庄亦雅,此人是个与人为善的好人、老实人至少不是坏人。他在越来越沉迷字画的时候,手头逐渐拮据起来……基于DSMA架构平台打造,起售9。39万,东风风神奕炫MAX在入门级紧凑家用轿车市场,9月1号正式上市的东风风神奕炫MAX吸引了很多年轻人,官方指导售价在9。3912。59万之间,一共推出6款车型,其中5款是燃油版,一款是混动车型。新款……华谊兄弟对上非誠勿擾婚介所?三战三胜《非诚勿扰》这部电影相信很多人就算没有看过也是听过的,这部电影是由冯小刚执导,葛优、舒淇、胡可等人主演的一部爱情喜剧片,讲述了男主秦奋的天才发明被投资人高价买断,一夜暴富的他开……电源能选长城巨龙吗?电源选购矿龙问题分析导读我相信很多和我一样的小伙伴,电脑只要够用就行,能不换就不换,能在省钱的基础上升级那就更不用说了,那么在之前的矿难当中,肯定有的小伙伴对长城巨龙电源毫不陌生,甚至都有点……扣丁学堂告诉你适合编程入门的语言怎么选现在是互联网时代,从事互联网开发行业的人们不论是薪资还是工作环境都是很让人羡慕的,因此有不少的小伙伴想要学习编程语言进入互联网行业,本篇文章扣丁学堂小编告诉你适合编程入门的语言……提升生活品质来苏宁嗨购五一厨电美容手机一网打尽五一长假马上就要到了,相信很多人已经拟定好计划了,有些人可能会宅在家中,有些人可能去旅游,有些人可能回家陪父母为了满足大家不同的计划,苏宁易购特意启动了嗨购五一,目前已经进入爆……贵阳市连续七年举办大数据电子商务职工职业技能大赛12月8日,以智领未来数说贵阳为主题的贵阳市第七届大数据电子商务职工职业技能大赛开赛。本届大赛由贵阳市总工会、贵阳市大数据发展管理局联合主办,旨在积极推进落实《新时期贵州……试驾体验上汽大众ID。4X一场科幻ID的探秘之旅大众ID。4是大众全新MEB电动车平台的首款电动车型,ID。4X(参数询价)作为上汽大众的首款电动紧凑型SUV,表现如何,这次就开着ID。4X来一场环球影城的探秘之旅,来和大家……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网