嘘~ 正在从服务器偷取页面 . . .

工欲善其事,必先利其器——协程(2)


resquests 协程的尝试

前面我们学习了协程的简单的语法,以及写了一段代码实现了简单的协程。而我们的目的是为了实现异步爬虫。所以我们就用 requests 模块尝试一下协程

flask服务

首先我们用 flask 设置一个简单的框架,因为我们的重点是协程,所以选择的网站越简单越好

代码如下

app = Flask(__name__)

@app.route('/bobo')
def index_bobo():
    time.sleep(2)
    return "hello bobo"

@app.route('/jay')
def index_jay():
    time.sleep(2)
    return "hello jay"

@app.route("/tom")
def index_tom():
    time.sleep(2)
    return "hello tom"

if __name__ == '__main__':
    app.run(threaded = True)

运行结果如下


我们会看到一个 url ,那个就是我们通过 flask 框架得到的一个根目录

resquests 模块的尝试

有了前期的准备工作,我们就可以试着通过 requests 模块进行协程的实现。

根据之前所学进行代码的编写

import asyncio
import requests
import time

async def get_url(url):
    print("正在下载", url)
    await asyncio.sleep(2)
    response = requests.get(url = 'http://127.0.0.1:5000/' + url)
    print("下载成功,", response.text)

if __name__ == '__main__':
    start = time.time()

    urls = ['bobo', "jay", "tom"]

    tasks = []
    for url in urls:
        task = asyncio.ensure_future( get_url(url) )
        tasks.append(task)

    loop = asyncio.get_event_loop()
    loop.run_until_complete( asyncio.wait( tasks ))

    print(time.time() - start)

但我们一运行程序就发现不对劲了,


明明我们使用了协程,为什么时间反而没有什么变化呢?这究竟是为什么呢?

aiohttp 模块实现协程

上面我们发现 requests 模块实现不了协程。这是为什么呢?

其实原因很简单,requests.get 是基于同步,要想实现协程必须使用基于异步的网络请求模块进行 url 的请求发送。所以我们使用 aiohttp模块,基于异步的网络请求模块。

至于怎么使用 aiohttp ,就直接看代码好了

import asyncio
import aiohttp
import time

async def get_url(url):
    print("正在下载", url)
    async with aiohttp.ClientSession() as session:
        async with await session.get(url = 'http://127.0.0.1:5000/' + url) as response:
            # text() 返回字符串形式的数据类型
            # read() 返回二进制形式的数据类型
            # json() 返回json串形式的数据类型
            # 注意:获取响应数据类型之前一定要用 await 进行手动挂起
            page = await response.text()
    print("下载成功,", page)

if __name__ == '__main__':
    start = time.time()

    urls = ['bobo', "jay", "tom"]

    tasks = []
    for url in urls:
        task = asyncio.ensure_future( get_url(url) )
        tasks.append(task)

    loop = asyncio.get_event_loop()
    loop.run_until_complete( asyncio.wait( tasks ))

    print(time.time() - start)

让我们来看一些运行结果,看看是不是空欢喜一场

运行时间确实是两秒,说明我们使用 aiohttp 实现了协程。


文章作者: New Ass
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 New Ass !
  目录