爬虫随笔(三) 并发并行协程
声明
本账号中的所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁,用于商业用途和非法用途,否则有此产生的一切后果均与作者无关!
性能优化
在使用爬虫获取内容时,我们发现,有些网站运行效率特别特别低,怎么提高效率呢?下面给出三个方法,并发,并行,协程。接下来我们详细讲讲其中区别以及运用
并发
我们常使用多线程来实现高效爬虫,什么是并发?在同一个进程中,通过时间片轮转的方法使运行函数'同时运行'(感官上),只使用一个进程,多任务来回切换,以下是使用方式
# -*- 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)
以上代码也展示了两种异步运行方式,可以自己尝试一下
再次声明
本文未经允许禁止转载,禁止任何修改后二次传播,擅自使用本文的讲解的技术而导致的任何意外,作者均不负责,若有侵权,请立刻联系我删除。同时感谢您的审阅与反馈!若您在阅读过程中发现任何表述不准确、逻辑不清晰或存在误导性的内容,请及时联系我进行修正。您的建议对提升内容质量至关重要,我将认真核对并优化。再次感谢您的指正,期待为您提供更专业、更严谨的技术解析与其他知识服务
本文来自博客园,作者:Liyukio,转载请注明原文链接:https://www.cnblogs.com/Liyukio/p/18722784
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构