提升爬虫效率:多线程,多进程,多协程

爬虫从入门到精通| 高并发爬虫-使用多线程/多进程/协程创建爬虫 多进程和多线程和协程创建的爬虫可以实现快速抓取 阅读详情

多线程爬虫

其核心原理是利用线程切换技术来实现CPU级别的并发执行。这种并发执行并不等同于多CPU的并行操作,而是在单个CPU上通过快速切换线程来模拟同时处理多个任务的效果。

爬虫使用多线程来处理网络请求,使用多线程来处理队列的URL,然后将URL返回结果放到另外一个队列只能够,其他线程再读取这个队列的数据。这种有种生产者,消费者的概念一样。

了解下queue

Python中的队列(queue)是一种先进先出(FIFO)的数据结构,可以使用标准库中的queue模块实现。以下是一个简单的示例:

import queue

# 创建一个队列
q = queue.Queue()

# 向队列中添加元素
q.put(1)
q.put(2)
q.put(3)

# 从队列中获取元素
print(q.get())  # 输出:1
print(q.get())  # 输出:2
print(q.get())  # 输出:3

多线程案例

  1. 首先定义两个队列来存放url,另一个用来放访问url后的html信息。
url_queue = queue.Queue()
html_queue = queue.Queue()
urls = [
    f"https://www.cnblogs.com/#p{page}"
    for page in range(1, 10 + 1)
]
for url in urls:
    url_queue.put(url)
  1. 定义一个生产者概念,源源不断往html_queue放数据
def craw(url):
    r = requests.get(url)
    return r.text

def do_craw(url_queue:queue.Queue, html_queue:queue.Queue):
    while True:
        url = url_queue.get()
        html = craw(url)
        html_queue.put(html)
        print(threading.current_thread().name,f"do_craw {url},size {url_queue.qsize()}")
        time.sleep(random.randint(1, 2))
  1. 定义一个消费者概念(解析)
def parser(html):
    soup = BeautifulSoup(html, 'html.parser')
    links = soup.find_all('a', 'post-item-title') # 标签,class
    return [(link['href'], link.get_text()) for link in links]

def do_parser(html_queue:queue.Queue):
    while True:
        html = html_queue.get()
        results = parser(html)
        for result in results:
            print(threading.current_thread().name, result,f"html_queue size:{html_queue.qsize()}")
        time.sleep(random.randint(1, 2))
  1. 开启线程
for idx in range(3):
    t = threading.Thread(target=do_craw, args=(url_queue,html_queue), name = f'do_craw{idx}')
    t.start()

for idx in range(2):
    t = threading.Thread(target=do_parser, args=(html_queue,), name=f'do_parser{idx}')
    t.start()
  1. 整体代码
import queue
import random
import threading
import time

import requests
from bs4 import BeautifulSoup

def craw(url):
    r = requests.get(url)
    return r.text

def do_craw(url_queue:queue.Queue, html_queue:queue.Queue):
    while True:
        url = url_queue.get()
        html = craw(url)
        html_queue.put(html)
        print(threading.current_thread().name,f"do_craw {url},size {url_queue.qsize()}")
        time.sleep(random.randint(1, 2))

def parser(html):
    soup = BeautifulSoup(html, 'html.parser')
    links = soup.find_all('a', 'post-item-title') # 标签,class
    return [(link['href'], link.get_text()) for link in links]

def do_parser(html_queue:queue.Queue):
    while True:
        html = html_queue.get()
        results = parser(html)
        for result in results:
            print(threading.current_thread().name, result,f"html_queue size:{html_queue.qsize()}")
        time.sleep(random.randint(1, 2))


if __name__ == '__main__':
    url_queue = queue.Queue()
    html_queue = queue.Queue()
    urls = [
        f"https://www.cnblogs.com/#p{page}"
        for page in range(1, 10 + 1)
    ]
    for url in urls:
        url_queue.put(url)

    for idx in range(3):
        t = threading.Thread(target=do_craw, args=(url_queue,html_queue), name = f'do_craw{idx}')
        t.start()

    for idx in range(2):
        t = threading.Thread(target=do_parser, args=(html_queue,), name=f'do_parser{idx}')
        t.start()

多进程爬虫

在计算机系统中,多个CPU同时执行不同的任务,以提高系统的处理能力和效率。在Python中,可以使用multiprocessing模块来实现多CPU并行,其实也叫多进程。

了解下Pool

Pool在Python的multiprocessing模块中是一个非常重要的类,它代表一个进程池。

进程池(Pool)是一种资源管理形式,它可以管理和控制多个进程的创建、执行和终止。通过使用进程池,可以有效地利用系统资源,提高程序运行效率。以下是对Pool类的一些详细解释:

  • 资源重用:Pool类可以创建一个进程池,其中的进程可以被重复使用。这意味着不需要为每个任务创建和销毁进程,从而减少了开销。
  • 自动管理:Pool类会自动管理进程的生命周期。当任务被提交到进程池时,它会选择一个可用的进程来执行该任务。如果没有可用的进程,任务会在队列中等待,直到有进程可用。
  • 任务队列:Pool类使用任务队列来存储待处理的任务。当进程池中有可用进程时,任务会从队列中取出并执行。
  • 并行处理:Pool类支持并行处理,即多个任务可以同时在不同的进程中执行。这有助于提高程序的执行速度,特别是在多核处理器上运行时。
  • 灵活性:Pool类提供了多种方法来提交任务,如map、imap、apply等,这些方法使得向进程池提交任务变得非常灵活和方便。
  • 上下文管理:Pool类支持作为上下文管理器使用,可以使用with语句来自动管理进程池的创建和销毁。

综上所述,理解Pool类是理解Python多进程编程的关键。通过使用Pool类,可以更高效地管理和执行多个进程,从而提高程序的性能。

1. apply

apply方法只能用于提交单个任务,并且需要指定任务的参数。如果要同时提交多个任务,可以使用map或imap方法。

from multiprocessing import Pool

def square(x):
    return x * x

if __name__ == "__main__":
    with Pool(processes=4) as pool:
        result = pool.apply(square, args=(2,))
        print("Result:", result)
2. apply_async

apply_async 允许你异步地执行一个函数。这个函数会在一个新的进程中运行,并且返回一个AsyncResult对象,你可以用这个对象来获取函数的结果。

from multiprocessing import Pool

def f(x):
    return x*x

if __name__ == '__main__':
    with Pool(5) as p:
        result = p.apply_async(f, (10,))
        print(result.get())
3. map

这将在进程池中的多个进程中并行执行square函数,并将结果存储在一个列表中。

from multiprocessing import Pool

def square(x):
    return x * x

if __name__ == "__main__":
    with Pool(processes=4) as pool:
        results = pool.map(square, range(10))
        print("Results:", results)
4. imap

Pool类中的imap方法与map方法类似,都是用于并行地执行函数。不过,imap方法在处理结果时稍有不同,它返回的是一个迭代器,而不是一个列表。这意味着你可以立即开始处理结果,而不需要等待所有任务完成。这对于处理大量数据或长时间运行的任务特别有用,因为它可以帮助减少内存使用并提高程序响应性。

from multiprocessing import Pool

def square(x):
    return x * x

if __name__ == "__main__":
    with Pool(processes=4) as pool:
        # imap返回一个迭代器
        results = pool.imap(square, range(10))
        # 遍历迭代器来获取结果
        for result in results:
            print("Result:", result)

多进程案例

import requests
from bs4 import BeautifulSoup
from multiprocessing import Pool
import os

def craw(url):
    r = requests.get(url)
    results = parser(r.text)  # 解析网页并提取所需信息
    for result in results:
        print("当前进程编号:", os.getpid())  # 打印当前进程编号
        print(result)


def parser(html):
    soup = BeautifulSoup(html, 'html.parser')
    links = soup.find_all('a', 'post-item-title') # 标签,class
    return [(link['href'], link.get_text()) for link in links]

if __name__ == '__main__':
    urls = [
        f"https://www.cnblogs.com/#p{page}"
        for page in range(1, 10 + 1)
    ]

    with Pool(processes=4) as pool:  # 创建一个包含4个进程的进程池
        pool.map(craw, urls)  # 使用进程池并发获取网页

多协程爬虫

多协程是指在一个线程中运行多个协程,它们通过任务的暂停和恢复来避免线程切换的开销,并且减少了锁的使用。

asyncio模块只能发tcp级别的请求,不能发http协议。

多协程案例

import asyncio
import aiohttp
from bs4 import BeautifulSoup

async def fetch(url):
    connector = aiohttp.TCPConnector(ssl=False)
    async with aiohttp.ClientSession(connector=connector) as session:
        async with session.get(url) as response:
            return await response.text()

async def main():
    urls = [
        f"https://www.cnblogs.com/#p{page}"
        for page in range(1, 10 + 1)
    ]
    tasks = [fetch(url) for url in urls]
    results = await asyncio.gather(*tasks)

    for result in results:
        pages = parser(result)
        for page in pages:
            print(page)

def parser(html):
    soup = BeautifulSoup(html, 'html.parser')
    links = soup.find_all('a', 'post-item-title')  # 标签,class
    return [(link['href'], link.get_text()) for link in links]



if __name__ == '__main__':
    asyncio.run(main())

首先定义了一个异步函数fetch,它使用aiohttp库异步获取给定URL的内容。然后,我们在main函数中创建了一个任务列表,其中每个任务都是对fetch函数的调用。我们使用asyncio.gather来并发执行所有任务,并等待它们全部完成。

爬虫并发及应用 HLSHLS(HTTP Live Streaming)是一种流媒体传输协议,最初由苹果公司开发并推出。它是一种基于HTTP的流媒体传输协议,旨在提供高质量的实时流媒体传输和适应不同网络条件的能力。HLS技术主要用于在互联网上实时传输音频和视频内容,通常用于直播活动、视频点播等场景。媒体分片(Media Segmentation):源视频或音频内容首先被分割成短小的媒体分片,通常每个分片持续几秒到十几秒不等。自适应码率(Adaptive Bitrate) 阅读详情

相关推荐

【爬虫】使用多线程、多进程、多协程提升爬虫速度

本系列为自己学习爬虫的相关笔记,如有误,欢迎大家指正 要学习提升爬虫速度用到的知识,必须先熟悉并发和并行、同步和异步的概 一、并发和并行,同步和异步 并发和并行 并发(concurrency)和并行(parallelism)是两个相似的概念。并发是指在一个时间段内发生若干事件的情况,并行是指在同一时刻发生若干事件的情况。 使用单核CPU和多核CPU来说就是:在使用单核CPU时,多个工作任务是以并发的方式运行的,因为只有一个CPU,所以各个任务会分别占用CPU的一段时间依次执行。如果在自己分得的时间段没有.

weixin_51656605的博客 5193

【Python 爬虫】多线程爬取

文章目录前言一、多进程库(multiprocessing)二、多线程爬虫三、案例实操四、案例解析1、获取网页内容2、获取每一章链接3、获取每一章的正文并返回章节名和正文4、将每一章保存到本地5、多线程爬取文章 前言 简单的爬虫只有一个进程、一个线程,因此称为单线程爬虫。单线程爬虫每次只访问一个页面,不能充分利用计算机的网络带宽。一个页面最多也就几百KB,所以爬虫在爬取一个页面的时候,多出来的网速和从发起请求到得到源代码中间的时间都被浪费了。如果可以让爬虫同时访问10个页面,就相当于爬取速度提高了10倍..

懂得一千零一种,赋予你失败的方法! 2万+

python3.6 多进程+协程的配合 提升爬虫效率?

多进程+协程是否能将采集效率翻倍

Aries8842的博客 5866

Python的多线程爬虫详解

Python 提供了两个支持多线程的模块,分别是 _thread 和 threading。其中 _thread 模块偏底层,它相比于 threading 模块功能有限,因此推荐大家使用 threading 模块。

Python966的博客 4395

【愚公系列】《Python网络爬虫从入门到精通》026-多进程爬虫

在信息爆炸的时代,数据的获取变得愈发重要。网络爬虫作为一种高效的数据采集工具,广泛应用于各个领域。然而,随着网络数据量的急剧增加,单线程爬虫的效率已难以满足需求。此时,多进程爬虫应运而生,成为提升数据抓取效率的重要手段。本文将探讨多进程爬虫的基本原理、优势以及实现方法,帮助你理解如何通过并行处理来加速数据采集过程。无论你是爬虫开发的新手,还是希望优化现有爬虫的工程师,这篇文章都将为你提供实用的指导和深入的见解。并行处理I/O密集型任务(如网络请求),显著减少总耗时。

愚公智库 12万+

多进程、多线程、协程的使用如何选择?

进程、线程与协程的差异总结背景基础概念1、进程2、线程3、协程各自的适用环境参考文献 背景 最近在研究如何实现高效率爬虫过程中,经常会使用多线程、多进程、以及协程来进行并发或并行操作。虽然掌握了这几个Python库的基本用法,但其实一直对这几个概念之间的区别理解不是那么明确,处在一种知其然,不知其所以然的处境,因此这几天查询了各种相关文献,总算是搞明白了进程、线程以及协程的内涵以及最佳使用场景,这篇博客可以算是学习记录与总结,记下来一遍日后有需要的时候再翻阅。 基础概念 在对比使用差别之前,首先看一下三者的

仙路尽头谁为峰 3238

Python-提升爬虫速度三种方式

一、提升爬虫速度 提示爬虫速度主要有3种方法: 多线程爬虫 多进程爬虫 多协程爬虫 二、并发与并行、同步和异步 并发是指在一个时间段内发生若干事件的情况。 并行是指在同一个时刻发生若干事件的情况。 当使用单核CPU时,多个工作任务就是以并发的方式运行的,因为只有一个CPU时,各个任务会分别占用CPU的一段时间依次执行。这种情况下,各个任务的时间段很短、经常切换,所以我们会感觉是“同时”进行,其...

qq_37246800的博客 8427

Python多线程Threading

Python并发编程简介 1.为什么要引入并发编程? 场景1:一个网络爬虫,按顺序爬取了1小时,采用并发下载减少到20分钟! 场景2:一个APP应用,优化前每次打开页面需要3秒钟,采用异步并发提升到每次200毫秒; 2.有哪些程序提速的方法? 3.python对并发编程的支持 怎样选择多线程Thread、多进程Process、多协程Coroutine 1.什么是CPU密集型计算、IO密集型计算? 2.多线程、多进程、多协程的对比 3.怎样根据任务选择对应技术? ...

fanfangyu的博客 2725

python爬虫之多线程、多进程爬虫

一、原因 多线程对爬虫的效率提高是非凡的,当我们使用python的多线程有几点是需要我们知道的: 1.Python的多线程并不如java的多线程,其差异在于当python解释器开始执行任务时,受制于GIL(全局解释所),Python 的线程被限制到同一时刻只允许一个程执行这样一个执行模型。 2.Python 的线程更适用于处理 I/O 和其他需要并发行的阻塞操作(比如等待 I/O、等待从数据库获取...

笑笑布丁的博客 4万+

【Python爬虫】提升爬虫的速度

提升爬虫的速度 提升爬虫的速度,主要有三种方法:多线程爬虫、多进程爬虫和多协程爬虫。 1.并发和并行,同步和异步 并发(concurrency):是指在一个时间段内发生若干事件的情况; 并行(parallelism):是指在同一个时刻发生若干事件的情况。 同步:就是并发或并行的各个任务不是独立运行的,任务之间有一定的交替顺序; 异步:则是并发或并行的各个任务可以独立运行,一个任务的运行...

小哲的博客 6189

基于python+mediapipe的手势拖动识别(无gpu)

手势点方块拖动

weixin_38029956的博客 5982

Python爬虫——多线程+协程threading+gevent

上一篇博客中我介绍了如何将爬虫改造为多进程爬虫,但是这种方法对爬虫效率的提升不是非常明显,而且占用电脑cpu较高,不是非常适用于爬虫。这篇博客中,我将介绍在爬虫中广泛运用的多线程+协程的解决方案,亲测可提高效率至少十倍以上。 本文既然提到了线程和协程,我觉得有必要在此对进程、线程、协程做一个简单的对比,了解这三个程之间的区别。 以下摘自这篇文章:http://www.cnblogs.c...

明月清風 1万+

dify离线部署

以bge-m3为例,本地部署bge-m3首先在一台能连网的linux服务器上(部署有ollama)创建想要保存模型的文件夹编辑ollama.service,配置ollama模型的保存路径添加模型存储地址将models目录设置属主,必须做,否则ollama无法启动重新加载配置文件并重启ollama测试ollama 运行是否正常最后拉取 bge-m3可在/opt/LLMModels/bge_m3/models目录下看到拉取得模型使用tar命令压缩文件夹。

weixin_42538734的博客 3070

Python----Python爬虫(多线程,多进程,协程爬虫)

该主要十利用多线程,多进程,线程池,进程池,协程爬取笔趣阁小说

weixin_64110589的博客 1768

BPMN2.0规范及流程引擎选型方案

本文主要简明扼要的介绍了BPMN2.0规范的内容,可让读者快速度的了解BPMN2.0所涵盖的主要内容和图形样式。也较为详细的阐述了如何绘制标准的流程图,以及在软件层面中如何实现业务流程功能,和技术选型。

比特桃 1万+

开源人形机器人硬件生态:关键技术、产业链与低成本突破 | OpenLoong 社区线下分享会

本文将深入探讨人形机器人硬件平台的关键技术、产业链与核心部件以及降低成本的策略。从硬件平台的核心技术,到机器人核心零部件的详细介绍,再到产业链各环节的协同发展以及实现低成本化的创新思路,将一同剖析人形机器人迈向广泛应用所面临的挑战与机遇,展望其未来的发展趋势,为开发者和相关从业者提供一些参考与启示。

OpenLoong_的博客 2420

Python 爬虫提速:【多进程、多线程、协程+异步】对比测试

Python 爬虫提速:【多进程、多线程、协程+异步】对比测试概念介绍测试环境开始测试测试【单线程单进程】测试【多进程 并行】测试【多线程 并发】测试【协程 + 异步】结果对比 Python 爬虫提速:【多进程、多线程、协程+异步】对比测试 概念介绍 首先简单介绍几个概念: 进程和线程: 进程就是一个程序在一个数据集上的一次动态执行过程(数据集是程序在执行过程中所需要使用的资源)。 线程也叫...

Python小蜗牛 4311

把 sy-* 带进 ABAP CDS:ABAP 7.50 里的环境信息新姿势($session 与 @Environment.systemField 实战)

摘要:ABAP 7.50在CDS视图中引入两种获取环境信息的方式:1)直接使用$session会话变量读取用户、客户端和系统语言;2)通过@Environment.systemField注解参数,由Open SQL自动注入系统字段。$session方式简单但依赖Open SQL访问路径,非ABAP环境下可能失效;注解参数方案更工程化,依赖关系明确且支持测试。建议ABAP体系内优先使用$session,对外接口采用参数化方案。两种方式各有适用场景,正确选择可避免潜在风险。(148字)

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 152

1.认识网络爬虫

1.认识网络爬虫 网络爬虫 爬虫的合法性 HTTP协议 请求与响应(重点) 网络爬虫 爬虫的全名叫网络爬虫,简称爬虫。他还有其他的名字,比如网络机器人,网络蜘蛛等等。爬虫就好像一个探测机器,它的基本操作就是模拟人的行为去各个网站溜达,点点按钮,查查数据,或者把看到的信息背回来。就像一只虫子在一幢楼里不知疲倦地爬来爬去。 你可以这样理解,每个爬虫都是你的分身。就像孙悟空拔了一撮汗毛,吹出一堆猴子一样。 你每天使用的百度,其实就是利用了这种爬虫技术:每天放出无数爬虫到各个网站,把他们的信

weixin_50804299的博客 5万+

Orange3实战教程:转换---预处理

部件提供了多种预处理方法,这些方法可以在单个预处理流程中组合使用。某些方法也可作为独立部件提供,支持更高级的技术和参数调整。连接到测试与评分:在交叉验证的每个批次中应用预处理器,随后学习器的预处理器会作用于预处理后的子集。连接到学习器:覆盖学习器的默认预处理流程,仅应用自定义流程(各学习器的默认步骤详见其文档)。直接连接到原始数据并输出预处理后的数据集,可能导致模型过拟合。:从原始数据中随机选择固定数量或百分比的特征,主要用于高级测试或教学用途。的预处理器输入,同时传入数据和学习器(如。

err2008的专栏 147

YOLOv12改进策略【Neck】| CGA Fusion:内容引导的注意力融合模块,空间权重引导的多模态特征自适应融合

本文记录的是利用CGA Fusion 模块改进 YOLOv12 的多模态融合部分。(Content-Guided Attention Fusion)通过内容引导注意力生成空间权重,引导高低层特征的自适应融合。本文利用模块,通过内容引导注意力生成空间权重,自适应地融合两个模态的特征,在特征融合阶段实现跨模态语义对齐与噪声抑制,增强对不同模态互补特征的利用能力,从而提升模型在多模态场景下的检测鲁棒性与准确性。DEA-Net: Single image dehazing based on detail-enhan

Limiiiing的博客 434

爬虫学习----提升爬虫的速度

一、并发和并行,同步和异步的概念 前面我们已经学习了网络爬虫的基本操作,下面,我们将会学习提升爬虫的速度,提升爬虫的速度有三种:多线程爬虫、多进程爬虫、多协程爬虫。在学习具体的操作之前,我们先来了解一下并发和并行,同步和异步的概念。 并发:在同一时间段内发生若干事件的情况,就是说任务一个接着一个执行,一个执行完成后执行下一个任务。 并行:在同一个时刻发生若干事件的情况。就是说同一时刻多个任务...

励志的小胡子 3571

第 10 篇:深度学习的“军火库”——CNN、RNN与Transformer,AI如何看懂世界?

深度学习的革命,不是依赖单一的通用大脑,而是为不同任务打造了专属“军火库”:CNN用“局部感知”看懂图像,RNN用“循环记忆”理解序列,而Transformer则用“全局注意力”开启了AIGC时代。理解这些架构,不是记忆孤立的技术,而是洞察AI从“专才”走向“通才”的进化脉络。

maqh_csdn的博客 786

Python高并发爬虫测评(2): 多进程, 多线程和异步协程哪个快?

在Python爬虫下一代网络请求库httpx和parsel解析库测评一文中我们对比了requests的同步爬虫和httpx的异步协程爬虫爬取链家二手房信息所花的时间(如下所示:一共580条...

大江狗 2585

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

浅谈网络爬虫

浅谈网络爬虫 什么是网络爬虫? 爬虫能干什么 搜索引擎 抢票、刷票等自动化软件 部分破解软件 金融等行业数据挖掘、分析数据来源 其他 爬虫很简单 语言的选择 两种语言的小demo 爬虫也不简单 ip、浏览器头(User-Agent)、和cookie限制 需登录的验证码限制、参数限制 JavaScript渲染/ajax加密 爬虫知识储备路线 1.基础语法: 2.正则和爬虫相关库,以及浏览器F12...

bigsai 1万+

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

[爬虫知识] 深入理解多进程/多线程/协程的异步逻辑

探讨了提升爬虫效率的三种异步技术方案。针对传统同步爬虫I/O等待的瓶颈问题,分析了多进程、多线程和协程的不同适用场景与代码示例。

2401_87328929的博客 1965

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

上一篇: Python并发编程基础
下一篇: 程序员入职第一天:新环境配置手册
大数据左右手
博客等级 码龄9年 475粉丝 116原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值