当前位置:   article > 正文

python 基于aiohttp的异步爬虫实战详解_asyncio.semaphore爬虫采集数据

asyncio.semaphore爬虫采集数据

这篇文章主要为大家介绍了python 基于aiohttp的异步爬虫实战详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

 

 引言

钢铁知识库,一个学习python爬虫、数据分析的知识库。人生苦短,快用python。

之前我们使用requests库爬取某个站点的时候,每发出一个请求,程序必须等待网站返回响应才能接着运行,而在整个爬虫过程中,整个爬虫程序是一直在等待的,实际上没有做任何事情。

像这种占用磁盘/内存IO、网络IO的任务,大部分时间是CPU在等待的操作,就叫IO密集型任务。对于这种情况有没有优化方案呢,当然有,那就是使用aiohttp库实现异步爬虫。

aiohttp是什么

我们在使用requests请求时,只能等一个请求先出去再回来,才会发送下一个请求。明显效率不高阿,这时候如果换成异步请求的方式,就不会有这个等待。一个请求发出去,不管这个请求什么时间响应,程序通过await挂起协程对象后直接进行下一个请求。

解决方法就是通过 aiohttp + asyncio,什么是aiohttp?一个基于 asyncio 的异步 HTTP 网络模块,可用于实现异步爬虫,速度明显快于 requests 的同步爬虫。

requests和aiohttp区别

区别就是一个同步一个是异步。话不多说直接上代码看效果。

安装aiohttp

1

pip install aiohttp

  • requests同步示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

#!/usr/bin/env python

# -*- coding: utf-8 -*-

# author: 钢铁知识库

import time

import requests

# 同步请求

def main():

    start = time.time()

    for i in range(5):

        res = requests.get('http://httpbin.org/delay/2')

        print(f'当前时间:{datetime.datetime.now()}, status_code = {res.status_code}')

    print(f'requests同步耗时:{time.time() - start}')

if __name__ == '__main__':

    main()

'''

当前时间:2022-09-05 15:44:51.991685, status_code = 200

当前时间:2022-09-05 15:44:54.528918, status_code = 200

当前时间:2022-09-05 15:44:57.057373, status_code = 200

当前时间:2022-09-05 15:44:59.643119, status_code = 200

当前时间:2022-09-05 15:45:02.167362, status_code = 200

requests同步耗时:12.785893440246582

'''

可以看到5次请求总共用12.7秒,再来看同样的请求异步多少时间。

  • aiohttp异步示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

#!/usr/bin/env python

# file: day6-9同步和异步.py

# author: 钢铁知识库

import asyncio

import time

import aiohttp

async def async_http():

    # 声明一个支持异步的上下文管理器

    async with aiohttp.ClientSession() as session:

        res = await session.get('http://httpbin.org/delay/2')

        print(f'当前时间:{datetime.datetime.now()}, status_code = {res.status}')

tasks = [async_http() for _ in range(5)]

start = time.time()

# Python 3.7 及以后,不需要显式声明事件循环,可以使用 asyncio.run()来代替最后的启动操作

asyncio.run(asyncio.wait(tasks))

print(f'aiohttp异步耗时:{time.time() - start}')

'''

当前时间:2022-09-05 15:42:32.363966, status_code = 200

当前时间:2022-09-05 15:42:32.366957, status_code = 200

当前时间:2022-09-05 15:42:32.374973, status_code = 200

当前时间:2022-09-05 15:42:32.384909, status_code = 200

当前时间:2022-09-05 15:42:32.390318, status_code = 200

aiohttp异步耗时:2.5826876163482666

'''

两次对比可以看到执行过程,时间一个是顺序执行,一个是同时执行。这就是同步和异步的区别。

aiohttp使用介绍

接下来我们会详细介绍aiohttp库的用法和爬取实战。aiohttp 是一个支持异步请求的库,它和 asyncio 配合使用,可以使我们非常方便地实现异步请求操作。asyncio模块,其内部实现了对TCP、UDP、SSL协议的异步操作,但是对于HTTP请求,就需要aiohttp实现了。

aiohttp分为两部分,一部分是Client,一部分是Server。下面来说说aiohttp客户端部分的用法。

基本实例

先写一个简单的案例

1

2

3

4

5

6

7

8

9

10

11

12

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号