高阶虫术:异步请求术

今天就介绍一个爬虫进阶的内容,利用异步请求库 aiohttp 来提升你的爬虫速度。

以前我有写过一篇文章,说的是很多人在学完一些高级特性,却一直不懂得如何使用,甚至越学越迷茫,导致学到最后只会对编程越来越厌倦。

我的建议是不管是什么高级的概念和技巧,一定要懂得高级概念能有什么作用,在项目中会怎么使用。通过具体的项目实战,对高级概念有个具体的认知,而不是只有空洞的表面学习。

这就好比你在玩游戏的时候,你懂得出这个装备会非常牛x,但具体牛x在哪里,就需要你回头认真的看装备属性的描述。

《虫术》这部书就是想让大家知道,不同等级的虫术之间会有什么效果,差别又有多大。对于具体的技术细节教程,我不会去讲解,因为这样就失去了小说原本的乐趣。但最后我会给出对应的技术教程文章,需要进一步了解的同学,自行学习。

所以今天我不会从最基础的概念来讲解什么是异步,什么是协程,我们就直接来看下用上来异步框架 aiohttp 的爬虫,到底有多牛逼。

aiohttp

aiohttp 是一个支持异步请求的库,利用它的 asyncio 配合我们可以非常方便地实现异步请求操作。

安装方式如下:

1 pip install aiohttp

 

然后我们直接来看下一个使用了 aiohttp 的爬虫和一个没有使用异步的爬虫,它们之间的速度到底差多少。

flask 请求环境

首先我利用 flask 库,在本地搭建一个网站,网站的内容非常的简单,先等待 3 秒,然后输出「高阶虫术:异步请求术」。

运行下面的代码需要你安装好 flask 的库。

安装方式如下:

1 pip install flask

 

程序代码:

 1 from flask import Flask
 2 import time
 3 
 4 app = Flask(__name__)
 5 
 6 @app.route("/")
 7 def index():
 8     time.sleep(3 )
 9     return "高阶虫术:异步请求术"
10 
11 if __name__ == '__main__':
12     app.run(threaded=True)

 

运行程序就会在「http://127.0.0.1:5000」地址输出「高阶虫术:异步请求术」。


虫者二段普通请求

本地测试环境都已搭建好,我们就可以开始创造我们的爬虫。首先身为虫者二段的我,第一反应想到的是利用 requests 库进行请求,随后我写下了下面的代码。

 1 import requests
 2 import time
 3 
 4 start = time.time()
 5 
 6 def get(url):
 7     response = requests.get(url)
 8     result = response
 9     return result
10 
11 def request():
12     url = "http://127.0.0.1:5000"
13     print("Wating for", url)
14     result = get(url)
15     print("Get response from", url, "Result:", result)
16 
17 
18 tasks = [request() for _ in range(100)]
19 end = time.time()
20 print("Cost time:", end - start)

我们通过循环来对本地地址进行 100 次的请求,最后输出总耗时数。

输出结果如下:

虫者二段所写的代码果然惨不忍睹,总耗时:300 多秒,慢的令人发指。

虫尊三段异步请求

随后在看了《虫术》之后,得到高人虫尊的指点习得「高阶虫术:异步请求术」我对上面的代码进行了修改。

 1 import asyncio
 2 import requests
 3 import aiohttp
 4 import time
 5 
 6 start = time.time()
 7 
 8 async def get(url):
 9     session = aiohttp.ClientSession()
10     response = await session.get(url)
11     result = await response.text()
12     session.close()
13     return result
14 
15 async def request():
16     url = "http://127.0.0.1:5000"
17     print("Wating for", url)
18     result = await get(url)
19     print("Get response from", url, "Result:", result)
20 
21 tasks = [asyncio.ensure_future(request()) for _ in range(100)]
22 loop = asyncio.get_event_loop()
23 loop.run_until_complete(asyncio.wait(tasks))
24 
25 
26 end = time.time()
27 print("Cost time:", end - start)

 

最后输出结果:

3.08 秒!在短短的 3 秒时间里,我就完成这 100 次的请求!速度提升了 100 倍!

爬虫的世界风云涌动,处处充满着危机,不同等级的虫师有着天与地的差别,唯有强大的虫师才能生存下来。

关于异步请求具体的细节,可以看崔庆才的这篇教程。

爬虫速度太慢?来试试用异步协程提速吧!

原文地址:https://www.cnblogs.com/chenlove/p/9682019.html