• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Python爬虫十四使用协程实现异步爬虫

武飞扬头像
camellia
帮助1

协程,又称微线程,纤程。英文名Coroutine。

asyncio是Python 3.4版本引入的标准库,直接内置了对异步IO的支持。划重点,python3.4及以上才可以使用协程

简单回顾一下:

Event_loop:事件循环,相当于一个无限循环,我们可以吧一些函数注册到这个时间循环上,当蛮须某些条件的时候,函数就会被循环执行

Countine:协程对象,我们可以将协程对象注册到事件循环中,他会被事件循环调用。我们可以使用async关键字来定义一个方法,这个方法在调用是不会立即被执行,而是返回一个协程对象。

Task:任务,他是对协程对象的进一步封装,包含了任务的各个状态。

Future:代表将来执行或还没有执行的任务,实际上和task没有本质区别,在Task的底层,一般不常用。

Async:定义一个协程

Await:用来挂起阻塞方法的执行

更多详情请移步《Python(三十八)python协程

这里我们简单的做一下回顾:

一:回顾

1:event_loop事件循环

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Time    : 2022/3/24 19:11
# @Author  : camellia
# @Email   : 805795955@qq.com
# @File    : asyncPaChong.py
# @Software: PyCharm

import asyncio

async def request(url):
    print("正在请求的url是",url)
    print("请求成功",url)

c = request("https://l.guanchao.site")

# 创建一个事件循环对象
loop = asyncio.get_event_loop()

# 将协程对象注册到loop中,然后启动loop
loop.run_until_complete(c)

执行上方代码,输出:

正在请求的url是 https://l.guanchao.site
请求成功 https://l.guanchao.site

2:task对象

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Time    : 2022/3/24 19:11
# @Author  : camellia
# @Email   : 805795955@qq.com
# @File    : asyncPaChong.py
# @Software: PyCharm

import asyncio

async def request(url):
    print("正在请求的url是",url)
    print("请求成功",url)

# task的使用
async def mains():
    task = [
        asyncio.create_task(request("https://l.guanchao.site"))
    ]
    print(task)
    done,pending = await asyncio.wait(task)
    print(task)

asyncio.run(mains())

执行代码输出:

[<Task pending coro=<request() running at F:\camellia\python\testProject\asyncPaChong.py:11>>]
正在请求的url是 https://l.guanchao.site
请求成功 https://l.guanchao.site
[<Task finished coro=<request() done, defined at F:\camellia\python\testProject\asyncPaChong.py:11> result=None>]

3:future对象

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Time    : 2022/3/24 19:11
# @Author  : camellia
# @Email   : 805795955@qq.com
# @File    : asyncPaChong.py
# @Software: PyCharm

import asyncio

async def request(url):
    print("正在请求的url是",url)
    print("请求成功",url)

c = request("https://l.guanchao.site")
# future 的使用
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(c)
print(task)
loop.run_until_complete(task)
print(task)

执行代码输出:

<Task pending coro=<request() running at F:\camellia\python\testProject\asyncPaChong.py:11>>
正在请求的url是 https://l.guanchao.site
请求成功 https://l.guanchao.site
<Task finished coro=<request() done, defined at F:\camellia\python\testProject\asyncPaChong.py:11> result=None>

4:回调方法(函数)

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Time    : 2022/3/24 19:11
# @Author  : camellia
# @Email   : 805795955@qq.com
# @File    : asyncPaChong.py
# @Software: PyCharm

import asyncio

async def request(url):
    print("正在请求的url是",url)
    print("请求成功",url)
    return url

c = request("https://l.guanchao.site")

def callback_func(task):
    print(task.result())

# 绑定回调
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(c)
# 将回调函数绑定到任务对象中,默认将task对象作为参数传入回调函数中
task.add_done_callback(callback_func)
print(task)
loop.run_until_complete(task)
print(task)

执行代码。输出:

<Task pending coro=<request() running at F:\camellia\python\testProject\asyncPaChong.py:11> cb=[callback_func() at F:\camellia\python\testProject\asyncPaChong.py:18]>
正在请求的url是 https://l.guanchao.site
请求成功 https://l.guanchao.site
https://l.guanchao.site
<Task finished coro=<request() done, defined at F:\camellia\python\testProject\asyncPaChong.py:11> result='https://l.guanchao.site'>

二:多任务协程爬虫实现

我这里使用图片下载来测试多任务协程,过程很简单,依次下载三张图片,使用协程,我们通过打印输出判断代码执行流程,代码如下图所示:

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Time    : 2022/3/24 19:11
# @Author  : camellia
# @Email   : 805795955@qq.com
# @File    : asyncPaChong.py
# @Software: PyCharm
import asyncio
import requests
import random
import string

async def request(url):
    print("开始下载:", url)
    loop = asyncio.get_event_loop()
    # awaitable loop.run_in_executor(executor, func, *args)
    # 参数: executor可以是ThreadPoolExecutor / ProcessPool, 如果是None,则使用默认线程池
    # requests模块默认不支持异步操作,所以就使用线程池来配合实现
    response = requests.get(url)
    print("下载完成")
    # 把图片保存到本地
    file_name = './img/'   ''.join(random.sample(string.ascii_letters   string.digits, 8))   '.jpg'
    with open(file_name, mode='wb') as file_object:
        file_object.write(response.content)

# task的使用
async def mains():
    task = [
        asyncio.create_task(request("https://resource.guanchao.site/uploads/sowing/welcome-image3.jpg")),
        asyncio.create_task(request("https://resource.guanchao.site/uploads/sowing/welcome-image5.jpg")),
        asyncio.create_task(request("https://resource.guanchao.site/uploads/sowing/welcome-image7.jpg"))
    ]
    print(task)
    done,pending = await asyncio.wait(task)
    print(task)

asyncio.run(mains())

执行代码输出:

[<Task pending coro=<request() running at F:\camellia\python\testProject\asyncPaChong.py:13>>, <Task pending coro=<request() running at F:\camellia\python\testProject\asyncPaChong.py:13>>, <Task pending coro=<request() running at F:\camellia\python\testProject\asyncPaChong.py:13>>]
开始下载: https://resource.guanchao.site/uploads/sowing/welcome-image3.jpg
下载完成
开始下载: https://resource.guanchao.site/uploads/sowing/welcome-image5.jpg
下载完成
开始下载: https://resource.guanchao.site/uploads/sowing/welcome-image7.jpg
下载完成
[<Task finished coro=<request() done, defined at F:\camellia\python\testProject\asyncPaChong.py:13> result=None>, <Task finished coro=<request() done, defined at F:\camellia\python\testProject\asyncPaChong.py:13> result=None>, <Task finished coro=<request() done, defined at F:\camellia\python\testProject\asyncPaChong.py:13> result=None>]

以上大概就是 协程在python爬虫中的应用。

有好的建议,请在下方输入你的评论。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgijehc
系列文章
更多 icon
同类精品
更多 icon
继续加载