zoukankan      html  css  js  c++  java
  • 高阶虫术:异步请求术

    今天就介绍一个爬虫进阶的内容,利用异步请求库 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 倍!

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

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

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

  • 相关阅读:
    CentOS安装JAVA后JAVA版本不对的问题
    AES加密时抛出 Illegal key size or default parameters
    Tomcat7 安装StartSSL证书笔记
    window无法启动mongodb服务:系统找不到指定的文件错误的解决方法
    springAop @AfterReturning注解 获取返回值
    springAop 使用@Around,@After等注解时,代码运行两边的问题
    htmlunit 导致高cup占用,一老内存溢出的解决办法
    spring activemq 整合
    springMVC整合Junit4进行单元测试
    socket,tcp,http三者之间的区别和原理
  • 原文地址:https://www.cnblogs.com/chenlove/p/9682019.html
Copyright © 2011-2022 走看看