20 | 揭秘 Python 协程

1. 一个爬虫的例子

import time

def crawl_page(url):
    print('crawling {}'.format(url))
    sleep_time = int(url.split('_')[-1])
    time.sleep(sleep_time)
    print('OK {}'.format(url))

def main(urls):
    for url in urls:
        crawl_page(url)

%time main(['url_1', 'url_2', 'url_3', 'url_4'])

########## 输出 ##########

crawling url_1
OK url_1
crawling url_2
OK url_2
crawling url_3
OK url_3
crawling url_4
OK url_4
Wall time: 10 s

scrawl_page 为函数休眠数秒,休眠时间取决于url最后的那个数字。

main()函数执行,调取craw_page()函数进行网络通信,经过若干秒等待后收到结果,然后执行下一个。

它也占用了不少时间,五个页面分别用了1秒到4秒的时间 ,加起来一共用了10秒,这样效率低,所以要优化,一个简单的思路就是并发化,用协程来写。

import asyncio

async def crawl_page(url):
    print('crawling {}'.format(url))
    sleep_time = int(url.split('_')[-1])
    await asyncio.sleep(sleep_time)
    print('OK {}'.format(url))

async def main(urls):
    for url in urls:
        await crawl_page(url)

%time asyncio.run(main(['url_1', 'url_2', 'url_3', 'url_4']))

########## 输出 ##########

crawling url_1
OK url_1
crawling url_2
OK url_2
crawling url_3
OK url_3
crawling url_4
OK url_4
Wall time: 10 s

import asyncio这个库包含了大部分我们实现协程所需的魔法工具

async修饰词声明异步函数,于是这里的craw_page和main都变成了异步函数,而调用异步函数,我们便可得到一个协程对象(coroutine object).

执行协程有多个方法,常用的三种:

await执行的效果,和python正常执行一样的,也就是说程序会阻塞在这,进入被调用的协程函数,执行完毕后再继续,而这也是await的字面意思,代码中await asynio.sleep(sleep_time)会在这里休息若干秒,await crawl_page(url)则会执行craw_page()函数。

asyncio.create_task()来创建任务,最后用asynicio.run来运行。

import asyncio

async def crawl_page(url):
    print('crawling {}'.format(url))
    sleep_time = int(url.split('_')[-1])
    await asyncio.sleep(sleep_time)
    print('OK {}'.format(url))

async def main(urls):
    tasks = [asyncio.create_task(crawl_page(url)) for url in urls]
    for task in tasks:
        await task

%time asyncio.run(main(['url_1', 'url_2', 'url_3', 'url_4']))

########## 输出 ##########

crawling url_1
crawling url_2
crawling url_3
crawling url_4
OK url_1
OK url_2
OK url_3
OK url_4
Wall time: 3.99 s

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值