Python学习,多进程了解一下!学爬虫不会用多进程能行吗?

简介: python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程。

python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程。Python提供了非常好用的多进程包multiprocessing,只需要定义一个函数,Python会完成其他所有事情。借助这个包,可以轻松完成从单进程到 并发执行的转换

本来想写多线程的,但是演示效果并不是很好,就改成进程了。

其实多进程没有我们想象的那么难,用几个小例子给大家分享一下!

目录

  • 多进程的多种实现方法及效果演示:这段将通过几个小脚本实现多进程的效果
  • 一个小爬虫实例,通过运行时间来查看进程对代码速度的影响

多进程

首先我们先做一个小脚本,就用turtle画4个同心圆吧!这样在演示多进程的时候比较直观。代码如下:

import turtle

def cir(n,m):
    turtle.penup()
    turtle.goto(n)
    turtle.pendown()
    turtle.circle(m)
    time.sleep(1)
def runn(lis1,lis2):
    for n, m in zip(lis1,lis2):
        cir(n,m)
if __name__ == '__main__':
    nn = [(0,-200),(0,-150),(0,-100),(0,-50)]
    mm = [200,150,100,50]
    runn(nn,mm)

这段代码,实现了画4个同心圆的效果,如果用多进程的话,我们稍微该写一下,将runn()函数替换下面的代码

from multiprocessing import Process,Pool

for i in range(4):
    Process(target=runn,args=(nn,mm)).start()

这里,启动4个进程,同时画圆,给个图大家感受一下!

可以看到,这里直接生成4个画板同时画同心圆。如果还要在加进程的话,可以用pool进程池,注意pool有2个方法,建议用非阻塞的p.apply_async不要用阻塞的p.apply方法,p.apply_async会由系统自行判断并运行,比如指定4个进程运行5个任务,那么会在某一个进程运行完毕的同时自动开始第5个任务,而阻塞的p.apply方法会一次只运行一个进程。

然后就是记得close()进程池,并用p.join()等待所有进程完成!相关代码如下

    p = Pool(9)
    for i in range(9):
        p.apply_async(runn,(nn,mm))#非阻塞
        #p.apply(runn,(nn,mm))#阻塞
    p.close()
    p.join()

Pool()里面不带参数会自动适应电脑本身内核数量,这里我设置9个进程同时进行!来看看效果

可以看到,同时进行了9个画图的进程,但是同样的,有明显的卡顿感!当然,我们也可以用map函数来写多进程,先修改下代码

def cir(m):
    turtle.penup()
    turtle.goto(m[0])
    turtle.pendown()
    turtle.circle(m[1])
    time.sleep(14)
if __name__ == '__main__':
    nn = [(0, -200), (0, -150), (0, -100), (0, -50)]
    mm = [200, 150, 100, 50]
    mn = [(x,y) for x,y in zip(nn,mm)]
    p = Pool(3)
    p.map(cir,mn)

这次不画4个同心圆了,我们让它4个进程各画一个圆,来看看效果

为了演示效果,多加了点间隔时间,并把cir函数的参数改为1个,这样便于生成元组列表!可以看到,有了明显的卡顿,电脑不好,大家看看效果就行了

写个简单的多进程爬虫

做一个小爬虫,加入运行时间,先上一个不使用进程的代码:

import requests
from lxml import etree
import time
from multiprocessing import Process,Pool

def main(url):
    time.sleep(1)
    html = requests.get(url)
    html.encoding = 'gb2312'
    data = etree.HTML(html.text)
    title = data.xpath('//a[@class="ulink"]/text()')
    summary = data.xpath('//td[@colspan="2"]/text()')
    urls = data.xpath('//a[@class="ulink"]/@href')
    for t,s,u in zip(title,summary,urls):
        print(t)
        print('【url:】http://www.dytt8.net'+u)
        print('【简介】>>>>>>>'+s)

if __name__ == '__main__':
    start = time.time()
    url = 'http://www.dytt8.net/html/gndy/dyzz/'
    pg_url = [url+'list_23_{}.html'.format(str(x)) for x in range(1,10)]
    for pg_u in pg_url:
        main(pg_u)
    end = time.time()
    print("共计用时%.4f秒"%(end-start))

在修改下多进程,直接修改最后几行行代码即可

    pg_url = [url+'list_23_{}.html'.format(str(x)) for x in range(1,10)]
    # for pg_u in pg_url:
    #   main(pg_u)
    p=Pool()
    p.map(main,pg_url)
    end = time.time()
    print("共计用时%.4f秒"%(end-start))

可以看到,速度提高了1倍多,当然,并不是说只能提高一倍,而是我的代码太简单了,只是从网站抓取字符串打印出来,响应速度很快,导致提升的倍率并没有我们想象的那么高,如果大家有兴趣,可以尝试一下,基本上可以提升到进程数的倍率,也就是说,不超过电脑核心数量,且没有其他外因(比如网络响应速度等等)的情况下,用4进程可以提升接近4倍的速度!

后记

在学习的过程中,难免会遇到很高深并且很难理解的知识点,我们可以先尝试去简化理解它,比如多进程,它本身还有进程池、进程间通讯、守护进程、进程类(重写run方法)、进程锁、进程队列、管道、信号量等等功能或知识点,这里都没有涉及,不过这并不影响我们使用简单的多进程写代码!

相关文章
|
21天前
|
Python 容器
Python学习的自我理解和想法(9)
这是我在B站跟随千锋教育学习Python的第9天,主要学习了赋值、浅拷贝和深拷贝的概念及其底层逻辑。由于开学时间紧张,内容较为简略,但希望能帮助理解这些重要概念。赋值是创建引用,浅拷贝创建新容器但元素仍引用原对象,深拷贝则创建完全独立的新对象。希望对大家有所帮助,欢迎讨论。
|
3天前
|
数据可视化 数据挖掘 大数据
1.1 学习Python操作Excel的必要性
学习Python操作Excel在当今数据驱动的商业环境中至关重要。Python能处理大规模数据集,突破Excel行数限制;提供丰富的库实现复杂数据分析和自动化任务,显著提高效率。掌握这项技能不仅能提升个人能力,还能为企业带来价值,减少人为错误,提高决策效率。推荐从基础语法、Excel操作库开始学习,逐步进阶到数据可视化和自动化报表系统。通过实际项目巩固知识,关注新技术,为职业发展奠定坚实基础。
|
12天前
|
Python
Python学习的自我理解和想法(10)
这是我在千锋教育B站课程学习Python的第10天笔记,主要学习了函数的相关知识。内容包括函数的定义、组成、命名、参数分类(必须参数、关键字参数、默认参数、不定长参数)及调用注意事项。由于开学时间有限,记录较为简略,望谅解。通过学习,我理解了函数可以封装常用功能,简化代码并便于维护。若有不当之处,欢迎指正。
|
10天前
|
数据采集 存储 缓存
如何使用缓存技术提升Python爬虫效率
如何使用缓存技术提升Python爬虫效率
|
11天前
|
数据采集 Web App开发 监控
Python爬虫:爱奇艺榜单数据的实时监控
Python爬虫:爱奇艺榜单数据的实时监控
|
20天前
|
数据采集 JSON API
如何利用Python爬虫淘宝商品详情高级版(item_get_pro)API接口及返回值解析说明
本文介绍了如何利用Python爬虫技术调用淘宝商品详情高级版API接口(item_get_pro),获取商品的详细信息,包括标题、价格、销量等。文章涵盖了环境准备、API权限申请、请求构建和返回值解析等内容,强调了数据获取的合规性和安全性。
|
23天前
|
存储 索引 Python
Python学习的自我理解和想法(6)
这是我在B站千锋教育学习Python的第6天笔记,主要学习了字典的使用方法,包括字典的基本概念、访问、修改、添加、删除元素,以及获取字典信息、遍历字典和合并字典等内容。开学后时间有限,内容较为简略,敬请谅解。
|
23天前
|
Python
Python学习的自我理解和想法(7)
学的是b站的课程(千锋教育),跟老师写程序,不是自创的代码! 今天是学Python的第七天,学的内容是集合。开学了,时间不多,写得不多,见谅。
|
22天前
|
存储 安全 索引
Python学习的自我理解和想法(8)
这是我在B站千锋教育学习Python的第8天,主要内容是元组。元组是一种不可变的序列数据类型,用于存储一组有序的元素。本文介绍了元组的基本操作,包括创建、访问、合并、切片、遍历等,并总结了元组的主要特点,如不可变性、有序性和可作为字典的键。由于开学时间紧张,内容较为简略,望见谅。
|
23天前
|
存储 索引 Python
Python学习的自我理解和想法(4)
今天是学习Python的第四天,主要学习了列表。列表是一种可变序列类型,可以存储任意类型的元素,支持索引和切片操作,并且有丰富的内置方法。主要内容包括列表的入门、关键要点、遍历、合并、判断元素是否存在、切片、添加和删除元素等。通过这些知识点,可以更好地理解和应用列表这一强大的数据结构。