13.网络爬虫—多进程详讲(实战演示)

news2024/9/25 9:31:52

网络爬虫—多进程详讲

  • 一·进程的概念
  • 二·创建多进程
  • 三·进程池
  • 四·线程池
  • 五·多进程和多线程的区别
  • 六·实战演示
    • 北京新发地线程池实战

前言
🏘️🏘️个人简介:以山河作礼。
🎖️🎖️:Python领域新星创作者,CSDN实力新星认证
📝​📝第一篇文章《1.认识网络爬虫》获得全站热榜第一,python领域热榜第一
🧾 🧾第四篇文章《4.网络爬虫—Post请求(实战演示)》全站热榜第八
🧾 🧾第八篇文章《8.网络爬虫—正则表达式RE实战》全站热榜第十二
🧾 🧾第十篇文章《10.网络爬虫—MongoDB详讲与实战》全站热榜第八,领域热榜第二
🎁🎁《Python网络爬虫》专栏累计发表十二篇文章,上榜四篇。欢迎免费订阅!欢迎大家一起学习,一起成长!!
💕💕悲索之人烈焰加身,堕落者不可饶恕。永恒燃烧的羽翼,带我脱离凡间的沉沦。

一·进程的概念

🧾 🧾进程是指计算机中正在执行的程序实例,它是操作系统进行资源分配和调度的基本单位。

  • 进程可以包含多个线程,每个线程负责执行不同的任务。
  • 进程之间相互独立,拥有独立的内存空间和资源,通过进程间通信来实现数据共享和协作。
  • 进程可以在计算机系统中运行多个,操作系统根据优先级和资源需求来调度进程的执行,以保证系统的稳定性和性能。

🧾 简单来说:

比如你打开了一个文本编辑器,这个文本编辑器就是一个进程。进程可以包含多个线程,每个线程负责执行不同的任务。比如,在一个音乐播放器中,可能有一个线程负责播放音乐,另一个线程负责显示歌曲信息。

操作系统会根据进程的优先级和资源需求来调度进程的执行。这样可以保证系统的稳定性和性能,避免出现一些进程占用过多资源而导致系统崩溃或变慢的情况。

总之,进程是一个非常重要的计算机概念,它是操作系统进行资源分配和调度的基本单位,也是我们使用计算机时经常接触到的概念之一。

二·创建多进程

🧾 🧾==Python创建多进程可以使用multiprocessing模块。该模块提供了一个Process类,可以用来创建新的进程。==

🧾 下面是一个简单的例子,展示如何使用multiprocessing模块创建多进程:

import multiprocessing

def worker(num):
    """子进程要执行的代码"""
    print('Worker %d is running' % num)

if __name__ == '__main__':
    # 创建5个子进程
    for i in range(5):
        p = multiprocessing.Process(target=worker, args=(i,))
        p.start()

上面的代码中,我们定义了一个worker函数,它接受一个参数num,用于标识该进程的编号。在主程序中,我们使用for循环创建了5个子进程,并且将worker函数作为参数传递给Process类的构造函数。然后,我们调用start方法启动子进程。

🧾 当我们运行这个程序时,会输出下面的结果:

Worker 0 is running
Worker 1 is running
Worker 2 is running
Worker 3 is running
Worker 4 is running

可以看到,5个子进程都在运行,并且输出了自己的编号。

除了使用Process类外,multiprocessing模块还提供了其他一些类和函数,用于创建和管理多进程。比如,我们可以使用Pool类来创建进程池,从而实现并发执行多个任务。

🧾 下面是一个使用Pool类的例子:

import multiprocessing

def worker(num):
    """子进程要执行的代码"""
    print('Worker %d is running' % num)

if __name__ == '__main__':
    # 创建进程池,最大进程数为3
    pool = multiprocessing.Pool(processes=3)
    
    # 将5个任务分配给进程池
    for i in range(5):
        pool.apply_async(worker, args=(i,))
    
    # 关闭进程池,等待所有任务执行完毕
    pool.close()
    pool.join()

上面的代码中,我们使用Pool类创建了一个进程池,最大进程数为3。然后,我们使用apply_async方法将5个任务分配给进程池。最后,我们调用close方法关闭进程池,并使用join方法等待所有任务执行完毕。

🧾 当我们运行这个程序时,会输出下面的结果:

Worker 0 is running
Worker 1 is running
Worker 2 is running
Worker 3 is running
Worker 4 is running

可以看到,5个任务被分配给了3个进程,并发执行。

三·进程池

🧾 🧾Python进程池是一种用于管理和调度多个进程的技术,它能够提高程序的并发性和效率。通过创建一个进程池,我们可以将多个任务分配给池中的进程,使得它们可以并行执行,从而加快程序的运行速度

🧾 创建多个进程,我们不用傻傻地一个个去创建。我们可以使用Pool模块来搞定。Pool 常用的方法如下:

方法含义
apply()同步执行(串行)
apply_async()异步执行(并行)
terminate()立刻关闭进程池
join()主进程等待所有子进程执行完毕。必须在close或terminate()之后使用
close()等待所有进程结束后,才关闭进程池

🧾 Pool类提供了一个简单的接口来创建进程池并管理多个进程。下面是一个简单的示例代码:

import multiprocessing

def func(x):
    return x*x

if __name__ == '__main__':
    with multiprocessing.Pool(processes=4) as pool:
        results = pool.map(func, [1, 2, 3, 4, 5])
        print(results)

在上面的代码中,我们定义了一个名为func的函数,它接受一个参数并返回其平方值。接下来,我们使用with语句创建了一个进程池,并指定了进程数为4。然后,我们使用map方法将任务分配给进程池中的进程,并将结果存储在results变量中。

在这个例子中,我们使用了map方法来将任务分配给进程池中的进程。map方法接受一个函数和一个可迭代对象作为参数,并返回一个列表,其中包含了函数对每个元素的处理结果。在这个例子中,我们将func函数和一个包含5个数字的列表作为参数传递给map方法,最终得到了一个包含5个数字平方值的列表。

四·线程池

🧾 🧾Python线程池和进程池类似,也是一种用于管理和调度多个线程的技术,它能够提高程序的并发性和效率
通过创建一个线程池,我们可以将多个任务分配给池中的线程,使得它们可以并行执行,从而加快程序的运行速度。

🧾 🧾Python中的线程池可以使用concurrent.futures模块中的ThreadPoolExecutor类来实现
ThreadPoolExecutor类提供了一个简单的接口来创建线程池并管理多个线程。下面是一个简单的示例代码:

import concurrent.futures

def func(x):
    return x*x

if __name__ == '__main__':
    with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
        results = executor.map(func, [1, 2, 3, 4, 5])
        print(list(results))

在上面的代码中,我们定义了一个名为func的函数,它接受一个参数并返回其平方值。接下来,我们使用with语句创建了一个线程池,并指定了线程数为4。然后,我们使用map方法将任务分配给线程池中的线程,并将结果存储在results变量中。

在这个例子中,我们使用了map方法来将任务分配给线程池中的线程。map方法接受一个函数和一个可迭代对象作为参数,并返回一个迭代器,其中包含了函数对每个元素的处理结果。在这个例子中,我们将func函数和一个包含5个数字的列表作为参数传递给map方法,最终得到了一个包含5个数字平方值的列表。

五·多进程和多线程的区别

在这里插入图片描述

🧾 🧾多线程和多进程都是用于提高程序并行处理能力的技术,但它们有以下几个方面的不同:

  1. 资源占用多进程需要更多的资源,每个进程都需要独立的内存空间、CPU时间片等,而多线程则共享进程的资源,每个线程只需独立的栈空间和程序计数器。

  2. 数据共享多进程之间的数据通信比较麻烦,需要使用IPC(进程间通信)技术,而多线程之间的数据共享比较容易,可以使用共享内存等方式。

  3. 稳定性多进程的稳定性比较高,一个进程崩溃不会影响其他进程的正常运行,而多线程的稳定性较差,一个线程崩溃可能会导致整个进程崩溃。

  4. 编程难度多线程的编程难度比较低,因为线程间的数据共享比较容易处理,而多进程的编程难度较高,因为进程间的数据共享需要使用IPC技术。

🧾 🧾程序一般属于两种类型:CPU密集型和I/O密集型。

  • CPU 密集型程序比较偏重于计算,需要经常使用CPU来运算。例如科学计算的程序,机器学习的程序等。
  • I/O 密集型顾名思义就是程序需要频繁进行输入输出操作。爬虫程序就是典型的I/O密集型程序。

如果程序是属于CPU密集型,建议使用多进程。而多线程就更适合应用于I/O密集型程序

六·实战演示

北京新发地线程池实战

1·任务目标 🔥 🔥使用线程池获取北京新发地蔬菜前一百页数据到csv文件中。
在这里插入图片描述

🎯2·按照之前学过的知识,我们一步一步来,按照普通的方法,先找数据,接着将数据获取到本地,然后在写入csv文件。

🎯3·通过查找数据和抓包,我们知道了数据在什么地方,接下来我们使用代码来将数据获取到本地:
在这里插入图片描述
🎯4·代码如下:(获取第一页数据的代码)


import requests

url = 'http://www.xinfadi.com.cn/getPriceData.html'

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'
}

json_data = requests.post(url, headers=headers).json()
print(json_data)

🎯5·数据如下:
在这里插入图片描述
🎯6·我们将数据解析放入csv文件中:

import csv

import requests

url = 'http://www.xinfadi.com.cn/getPriceData.html'

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'
}

head = ['id', 'prodName', 'prodCatid', 'prodCat', 'prodPcatid', 'prodPcat', 'lowPrice', 'highPrice', 'avgPrice',
        'place', 'specInfo', 'unitInfo', 'pubDate', 'status', 'userIdCreate', 'userIdModified', 'userCreate',
        'userModified', 'gmtCreate', 'gmtModified']

f = open('data.csv', 'w+', encoding='gbk', newline='')
csv_file = csv.writer(f)
csv_file.writerow(head)

json_data = requests.post(url, headers=headers).json()
# print(json_data)
for dict_obj in (json_data['list']):

    data_list = []
    for j in head:
        data_list.append(dict_obj[j])
    csv_file.writerow(data_list)
f.close()

在这里插入图片描述
🎯7·这是第一页数据,完成了一大步。接着我们开始写循环,并且使用线程池来帮助我们更快的获取数据到本地。

🎯8·重要的代码我都写上了注释方便理解,就不在代码片以外做过多的解释;

import csv
from concurrent.futures import ThreadPoolExecutor

import requests

url = 'http://www.xinfadi.com.cn/getPriceData.html'

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'
}

# 字段
head = ['id', 'prodName', 'prodCatid', 'prodCat', 'prodPcatid', 'prodPcat', 'lowPrice', 'highPrice', 'avgPrice',
        'place', 'specInfo', 'unitInfo', 'pubDate', 'status', 'userIdCreate', 'userIdModified', 'userCreate',
        'userModified', 'gmtCreate', 'gmtModified']

# 创建csv文件
f = open('data.csv', 'w+', encoding='gbk', newline='')
csv_file = csv.writer(f)
csv_file.writerow(head)

#   创建了一个名为pool的ThreadPoolExecutor对象,其中线程池大小为20。20为最大线程数量  
pool = ThreadPoolExecutor(20)


def data_get(page):  # 定义了一个名为data_get的函数,用于获取每一页的数据,并将数据存储到CSV文件中。函数中的参数page表示当前页数。
    data = {
        'limit': 20,
        'current': page
    }
    #定义了一个名为data的字典,用于存储POST请求的参数。然后使用requests库发送POST请求,并将返回的JSON数据转换为字典格式。
    json_data = requests.post(url, headers=headers, data=data).json()
    for dict_obj in (json_data['list']): #使用for循环遍历每一个字典对象,并将需要的数据存储到一个列表中。最后,使用csv库将数据写入到CSV文件中。

        data_list = []
        for j in head:
            data_list.append(dict_obj[j])  # i是一个字典 j是key

        print(page, data_list)
        # 存储数据 安行写入数据
        csv_file.writerow(data_list)


for index in range(1, 1 + 100):  # 循环页数
    pool.submit(data_get, index)  # 将数据存入线程池
#在主函数中使用for循环遍历每一页数据,并将每一页数据提交给线程池中的线程进行处理。具体地,使用pool.submit()方法将数据提交给线程池中的线程。
# 是否等线程全部结束继续往下面运行,相当于多线程的join()
pool.shutdown(True)  #使用pool.shutdown(True)方法等待所有线程结束。其中,参数True表示等待所有线程结束后再继续往下执行。
# 关闭文件,将数据存入到文件
f.close()

在这里插入图片描述
在这里插入图片描述

🎯9·任务目标到此就算完成,使用线程池获取数据能提高效率和节省资源,提高稳定性等。想要熟练的使用线程池就必须了解线程池的基本概念和原理,学习线程池的实现方法,然后练习使用线程池解决实际问题。

写在最后:
👉👉本专栏所有文章是博主学习笔记,仅供学习使用,爬虫只是一种技术,希望学习过的人能正确使用它
博主也会定时一周三更爬虫相关技术更大家系统学习,如有问题,可以私信我,没有回,那我可能在上课或者睡觉,写作不易,感谢大家的支持!!🌹🌹🌹

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/430607.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spark SQL实战(07)-Data Sources

1 概述 Spark SQL通过DataFrame接口支持对多种数据源进行操作。 DataFrame可使用关系型变换进行操作,也可用于创建临时视图。将DataFrame注册为临时视图可以让你对其数据运行SQL查询。 本节介绍使用Spark数据源加载和保存数据的一般方法,并进一步介绍…

node安装

一、下载nodejs的安装包: 下载地址:https://nodejs.org/zh-cn/download 根据自己电脑系统及位数选择,一般都选择windows64位.msi格式安装包 二、改变nodejs的下载依赖包路径 安装完nodejs后,也同时安装了npm, npm是…

半监督语义分割_paper reading part1

Assignment 要解决的问题思路方法结果自己的想法 01 A Survey on Semi-Supervised Semantic Segmentation University of Granada, 18071, Granada, Spain 2023.02出版 problem to solve ss先前的(19年)不适用先前的调研包含弱监督,ss不…

Docker Desktop使用PostgreSql配合PGAdmin的使用

在看此教程之前,请先下载安装Docker Desktop 安装成功可以查看版本 然后拉取postgresql的镜像:docker pull postgres:14.2 版本可以网上找一个版本,我的不是最新的 发现会报一个问题 no matching manifest for windows/amd64 10.0.19045 i…

小心,丢失的消息!RocketMQ投递策略帮你解决问题!博学谷狂野架构师

RocketMQ消息投递策略 作者: 博学谷狂野架构师GitHub:GitHub地址 (有我精心准备的130本电子书PDF)只分享干货、不吹水,让我们一起加油!😄 前言 RocketMQ的消息投递分分为两种:一种是生产者往MQ …

java中级面试题

1.假如有两个线程共同操作数据库,以乐观锁的角度考虑,怎么确保不会发生并发问题? PS:考点是CAS,比较并替换。CAS中有三个值,内存中的值,新值,旧值。 假如内存中的值是2000&#xf…

[C++]string类的模拟实现和相关函数的详解

目录string总体架构具体实现默认成员函数构造函数构造拷贝函数析构函数赋值重载[]相关操作函数c_str() && size()reserve() && resize()push_back() && append()find()inserterase() && clear其余操作符重载< 、 <、 >、 >、 !<…

【系统集成项目管理工程师】项目整体管理

&#x1f4a5;十大知识领域&#xff1a;项目整体管理 项目整体管理包括以下 6 个过程: 制定项目章程定项目管理计划指导与管理项目工作监控项目工作实施整体变更控制结束项目或阶段过程 一、制定项目章程 制定项目章程。编写一份正式文件的过程&#xff0c;这份文件就是项目章程…

某程序员哀叹:月薪四五万,却每天极度焦虑痛苦,已有生理性不适,又不敢裸辞,怎么办?

高薪能买来快乐吗&#xff1f; 来看看这位程序员的哀叹&#xff1a; 实在是扛不住了&#xff0c;每天都在极度焦虑和痛苦中度过&#xff0c;早上起来要挣扎着做心理建设去上班&#xff0c;已经产生生理性的头晕恶心食欲不振。有工作本身的原因&#xff0c;更多是自己心态的问…

OpenCV+FFmpeg 实现人脸检测Rtmp直播推流(Python快速实现)

实现效果 windows平台笔记本摄像头视频采集、人脸识别&#xff0c;识别后将视频推流到RTMP流媒体服务器&#xff0c;在任意客户端可以进行RTMP拉流播放。 效果如图&#xff1a; 使用VLC播放器进行拉流。 准备工作 需要先安装OpenCV的python包以及FFmpeg。 对于ffmpeg有两…

Java——删除链表中重复的节点

题目链接 牛客在线oj题——删除链表中重复的节点 题目描述 在一个排序的链表中&#xff0c;存在重复的结点&#xff0c;请删除该链表中重复的结点&#xff0c;重复的结点不保留&#xff0c;返回链表头指针。 例如&#xff0c;链表 1->2->3->3->4->4->5 处…

【Vue】学习笔记-数据代理

数据代理 Object.defineproperty方法 <script type"text/javascript">let number18let person{name:张三,sex:男,}//age属性 不参与遍历Object.defineProperty(person,age,{//value:18,//enumerable:true, //控制属性是否可以枚举&#xff0c;默认值是false//…

科技成果评价最新攻略,你确定不来看看?

一、什么是科技成果评价&#xff1f; 是指按照委托者的要求&#xff0c;由具有评价资质的第三方专业机构聘请专家&#xff0c;坚持实事求是、科学民主、客观公正、注重质量、讲求实效的原则&#xff0c;依照规定的程序和标准&#xff0c;对被评价科技成果进行审查与辨别&#…

[Java Web]VUE | vue:一项Java Web开发中不可或缺的前端技术

⭐作者介绍&#xff1a;大二本科网络工程专业在读&#xff0c;持续学习Java&#xff0c;努力输出优质文章 ⭐作者主页&#xff1a;逐梦苍穹 ⭐所属专栏&#xff1a;Java Web ⭐如果觉得文章写的不错&#xff0c;欢迎点个关注一键三连&#x1f609;有写的不好的地方也欢迎指正&a…

AD19 基础应用技巧(快速定义PCB板框,CAD中DWG转DXF格式导入)

【B站一个假的攻城狮】导入CAD图纸到PCB&#xff0c;Altium Designer 21教程&#xff0c;第九节。 http://www.keyboard-layout-editor.com/ http://builder.swillkb.com/ 1、打开中望CAD&#xff0c;并打开一张图纸文件&#xff0c;为了能把孔表达清楚&#xff0c;开孔断面图…

React(六) —— redux

&#x1f9c1;个人主页&#xff1a;个人主页 ✌支持我 &#xff1a;点赞&#x1f44d;收藏&#x1f33c;关注&#x1f9e1; 文章目录⛳Redux&#x1f346;redux定义&#x1f490;redux使用原则&#x1f370;redux使用场景&#x1f9ca;redux工作流程&#x1f96b;redux基本创建…

14.创建组件

组件可以理解为页面的拼图块&#xff0c;一个完整的页面是由若干个组件拼成的 在vue中规定&#xff0c;组件的后缀名为vue&#xff0c;每一个vue文件中应该包含三个大标签 template 组件的模板结构&#xff0c;可以理解为htmlscript 组件的JS&#xff0c;控制组件要执行什么动…

区域检验管理系统(云LIS)源码

1、区域检验管理系统&#xff08;云LIS&#xff09;概述 云LIS是为区域医疗提供临床实验室信息服务的计算机应用程序&#xff0c;可协助区域内所有临床实验室相互协调并完成日常检验工作&#xff0c;对区域内的检验数据进行集中管理和共享&#xff0c;通过对质量控制的管理&am…

Java每日一练(20230418)

目录 1. N皇后 II &#x1f31f;&#x1f31f;&#x1f31f; 2. 字符串相乘 &#x1f31f;&#x1f31f; 3. 买卖股票的最佳时机 &#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一…

“Natural Earth II“ === “Natural Earth II“是false?你知道空 格的四种写法吗?

前言 有一回对我说道&#xff0c;“你学过前端么&#xff1f;”我略略点一点头。他说&#xff0c;“学过前端&#xff1f;……我便考你一考。html 里面的空格&#xff0c;怎样 coding 的&#xff1f;”我想&#xff0c;讨饭一样的人&#xff0c;也配考我么&#xff1f;便回过脸…