爬虫随笔(三) 并发并行协程

声明

  本账号中的所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁,用于商业用途和非法用途,否则有此产生的一切后果均与作者无关!

性能优化

  在使用爬虫获取内容时,我们发现,有些网站运行效率特别特别低,怎么提高效率呢?下面给出三个方法,并发,并行,协程。接下来我们详细讲讲其中区别以及运用

并发

  我们常使用多线程来实现高效爬虫,什么是并发?在同一个进程中,通过时间片轮转的方法使运行函数'同时运行'(感官上),只使用一个进程,多任务来回切换,以下是使用方式

# -*- coding:utf-8 -*-
# @FileName  :多线程练习.py
# @Time      :2025/2/14 13:11
# @Author    :Yukio
from threading import Thread

# def func(name):
#     for i in range(10):
#         print(name,i)

# class MyThread(Thread):
#     def __init__(self,name):
#         super().__init__()
#         self.name = name
# 
#     def run(self):
#         for i in range(100):
#             print(self.name,i)

if __name__ == "__main__":
    '''
    第一种
    t1 = Thread(target=func,args=("t1",))
    t2 = Thread(target=func,args=("t2",))
    t1.start()
    t2.start()
    '''
    '''
    第二种方式
    t1 = MyThread("t1")
    t2 = MyThread("t2")
    t1.start()
    t2.start()
    '''

  并发也是爬虫开发中使用比较常见的方法。使用一个进程多任务来回切换,我举一个例子:比如说人是一台机器,我就是一个进程,现在我给我自己定下任务,1.烧水。2,煮饭。3,洗澡。如果我按照程序执行的话,我会烧水,烧完水以后再去煮饭,煮完饭以后去洗澡,而在具体使用中,我们会发现,在烧水时,我们可以去煮饭,烧水煮饭都给他定时定好以后,我们可以去洗澡。只有三个任务都可以运行了。

并行

  多进程是并行的使用体现,和并发不一样的地方就是,并发使用一个进程,而并行使用多个进程,进程越多,速度越快。缺点就是资源开销比较大。以下是并行使用方法

# -*- coding:utf-8 -*-
# @FileName  :多进程.py
# @Time      :2025/2/14 21:39
# @Author    :Yukio
from multiprocessing import Process,Queue

def pr(name):
   for i in range(100):
       print(name)

def gg(name):
   for i in range(100):
       print('gg'+name)
"""
多进程连接可以用队列写
而这个队列的包有且只有
from multiprocessing import Queue

"""
if __name__ == "__main__":
   p1 = Process(target=pr, args=("hello",))
   p2 = Process(target=gg, args=("world",))
   p1.start()
   p2.start()

  而并行使用多个进程,进程越多,速度越快,举个例子:现在我有一个工厂,工厂里只有一条流水线,我每天产能都是固定的,但是,我又花了几十万多加了几条流水线,我的产能会不会增加?
  在使用过程中,我们可以给不同进程传入一个全局队列,这个队列可以放我们所需要进程相互串联的东西。

协程

  协程,在爬虫实际使用中非常常见,在网络请求以及文件读写中都产生阻塞,其也是在一个进程中运行,任务被分成多个协程,根据事件循环来回切换。在一个协程中,如果我遇到阻塞,我就会切换到另一个协程,然后运行,一直到我遇到阻塞的协程运行完,我再运行,以下是使用方法

# -*- coding:utf-8 -*-
# @FileName  :协程.py
# @Time      :2025/2/15 00:58
# @Author    :Yukio
import asyncio
import time


#
# async def func():
#     print('协程')
#
# if __name__ == "__main__":
#     # event_loop = asyncio.get_event_loop()
#     # event_loop.run_until_complete(func())
#     asyncio.run(func())
async def func1():
    print('协程')
    await asyncio.sleep(1)
    print('结束')
    return '协程1'

async def func2():
    print('协程1')
    await asyncio.sleep(2)
    print('结束1')
    return '协程2'

async def func3():
    print('协程2')
    await asyncio.sleep(3)
    print('结束2')
    return '协程3'

async def main():
    task = [
        asyncio.create_task(func2()),
        asyncio.create_task(func1()),
        asyncio.create_task(func3())
    ]
    # 返回是无序的,是个set类型
    # done,pending = await asyncio.wait(task)
    # print(done)
    # for i in done:
    #     print(i.result())

    # 返回有序,return_exceptions = False返回错误信息,并且不继续执行了

    result = await asyncio.gather(*task)#return_exceptions = False
    print(result)

if __name__ == '__main__':
    start = time.time()
    asyncio.run(main())
    print('总耗时', time.time() - start)

  以上代码也展示了两种异步运行方式,可以自己尝试一下

再次声明

  本文未经允许禁止转载,禁止任何修改后二次传播,擅自使用本文的讲解的技术而导致的任何意外,作者均不负责,若有侵权,请立刻联系我删除。同时感谢您的审阅与反馈!若您在阅读过程中发现任何表述不准确、逻辑不清晰或存在误导性的内容,请及时联系我进行修正。您的建议对提升内容质量至关重要,我将认真核对并优化。再次感谢您的指正,期待为您提供更专业、更严谨的技术解析与其他知识服务

posted @   Liyukio  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示