Python提供了一些强大的异步框架,帮助我们处理并发任务,提高程序运行效率。我们接下来将主要介绍两个框架:asyncioaiohttp

1. asyncio

asyncio是Python标准库中的一个用于编写单线程并发代码的模块,使用事件循环驱动的协程。它允许我们使用async/await语法编写并发代码。

基本使用

我们可以通过以下代码来创建一个简单的异步任务:

import asyncio

async def hello():
    print('Hello World')

loop = asyncio.get_event_loop()
task = loop.create_task(hello())
loop.run_until_complete(task)

在上面的例子中,我们首先定义了一个异步函数hello,然后通过loop.create_task方法创建了一个任务,最后用loop.run_until_complete方法来运行这个任务。

并发运行

在进行网络爬虫时,我们可以用asyncio并发地运行多个网络请求,提高爬虫的效率:

import asyncio

async def fetch_url(url):
    print(f'Start fetching {url}')
    await asyncio.sleep(2)  # 模拟网络请求
    print(f'Finish fetching {url}')

urls = ['url1', 'url2', 'url3']
loop = asyncio.get_event_loop()
tasks = [loop.create_task(fetch_url(url)) for url in urls]
loop.run_until_complete(asyncio.wait(tasks))

2. aiohttp

虽然asyncio提供了异步I/O的基本功能,但它并没有提供进行HTTP请求的工具。这就是aiohttp库的作用。

基本使用

以下是一个基本的aiohttp请求示例:

import aiohttp
import asyncio

async def fetch(session, url):
    async with session.get(url) as response:
        return await response.text()

async def main():
    async with aiohttp.ClientSession() as session:
        html = await fetch(session, 'http://python.org')
        print(html)

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

在上面的例子中,我们首先创建了一个ClientSession对象,然后用这个对象的get方法发起了一个GET请求,最后用response.text()方法获取了响应的文本内容。

并发请求

在进行网络爬虫时,我们可以用aiohttpasyncio一起并发地运行多个HTTP请求,提高爬虫的效率:

import aiohttp
import asyncio

async def fetch(session, url):
    async with session.get(url) as response:
        return await response.text()

async def main():
    urls = ['http://python.org', 'http://www.google.com', 'http://www.apple.com']
    tasks = []
    async with aiohttp.ClientSession() as session:
        for url in urls:
            task = fetch(session, url)
            tasks.append(task)
        htmls = await asyncio.gather(*tasks)
        for url, html in zip(urls, htmls):
            print(url, len(html))

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

在上面的例子中,我们用了asyncio.gather函数来并发地运行多个fetch任务,并通过zip函数来将每个URL与其对应的HTML内容打印出来。
推荐阅读:

https://mp.weixin.qq.com/s/dV2JzXfgjDdCmWRmE0glDA

https://mp.weixin.qq.com/s/an83QZOWXHqll3SGPYTL5g

file


移动安全星球
1 声望2 粉丝