python多线程案例
目录
- 进程介绍
- 线程和进程之间的对比
- 进程之间的通信
- 进程池之间的通信
- 进程和线程的区别
- 爬取王者荣耀的高清图片
进程介绍
进程:正在执行的程序
程序:没有执行的代码,是一个静态的
线程和进程之间的对比
进程:能够完成多任务,一台电脑上可以同时运行多个QQ
线程:能够完成多任务,一个QQ中的多个聊天窗口
根本区别:进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位
进程之间的通信
Queue-队列 先进先出
共享全局变量不适用于多进程编程
进程池之间的通信
当需要创建的子进程数量不多时,可以直接利用multiprocessing中的Process动态生成多个进程,但是如果是上百甚至上千个目标,手动的去创建的进程的工作量巨大,此时就可以用到multiprocessing模块提供的Pool方法
from multiprocessing import Poolimport os,time,randomdef worker(msg):t_start = time.time()print('%s开始执行,进程号为%d'%(msg,os.getpid()))time.sleep(random.random()*2)t_stop = time.time()print(msg,"执行完成,耗时%0.2f"%(t_stop-t_start))if __name__ == '__main__':po = Pool(3) # 定义一个进程池for i in range(0,10):po.apply_async(worker,(i,)) print("--start--")po.close() po.join() print("--end--")
进程和线程的区别
- 进程
系统中正在运行的应用程序
1个CPU 1次只能执行1个进程,其它的进程处于非运行状态
N个CPU核心可以同时执行N个任务 - 线程
进程中包含的执行单元 1个进程可以包含多个线程
Python当中 1次只能执行1个线程 阻塞(等待)
锁 防止多个线程之间共享资源
爬取王者荣耀的高清图片
- 普通方式爬取图片
1 我们发现数据不在网页源码当中,然后通过NetWork 找到了一个数据接口 worklist
2 response 复制到了json.cn网站 数据是错误的 jsoncallback=Jquery的数据删掉
3 每一个Object就是一组图片 sProdImgNo_1 是封面小图
通过编号来获取不同规格的图片
发现图片的url做了编码了 用parse.unquote 进行解码
import requests
from urllib import parse
import os
from urllib import requestheaders = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ''Chrome/87.0.4280.141 Safari/537.36','referer': 'https://pvp.qq.com/'
}
# 定义一个函数 来获取不同规格图片的url
def extract_images(data):image_urls = []for x in range(1, 9):image_url = parse.unquote(data['sProdImgNo_%d' % x]).replace('200', '0')image_urls.append(image_url)return image_urlsdef main():# 目标urlpage_url = 'https://apps.game.qq.com/cgi-bin/ams/module/ishow/V1.0/query/workList_inc.cgi?activityId=2735' \'&sVerifyCode=ABCD&sDataType=JSON&iListNum=20&totalpage=0&page=0&iOrder=0&iSortNumClose=1' \'&iAMSActivityId=51991&_everyRead=true&iTypeId=2&iFlowId=267733&iActId=2735&iModuleId=2735&_' \'=1611144188371 'res = requests.get(page_url, headers=headers)# print(res.text) json类型的str# print(type(res.json()),res.json())result = res.json()datas = result['List']a = 1for data in datas:# 获取图片的url 并做一个处理 200 --> 0# sProdImgNo_1 = parse.unquote(data['sProdImgNo_1']).replace('200','0')# sProdImgNo_2 = parse.unquote(data['sProdImgNo_2']).replace('200', '0')# sProdImgNo_3 = parse.unquote(data['sProdImgNo_3']).replace('200', '0')# print(sProdImgNo_1)image_urls = extract_images(data)# 获取图片的名字name = parse.unquote(data['sProdName'])# print('='*80)# print(name)# print(image_urls)# print('='*80)# 创建文件夹 image\亚瑟-潮玩骑士王\1.jpg 2.jpg 3.jpgdirpath = os.path.join('image', name + str(a))os.mkdir(dirpath)a += 1for index, image_url in enumerate(image_urls):request.urlretrieve(image_url, os.path.join(dirpath, '%d.jpg' % (index + 1)))print('%s下载完成' % name)if __name__ == '__main__':main()
- 多线程的方式爬取图片
思路: 队列1存放的是每一页的url地址 生成者去请求并解析每一页的url地址(主要目的是获取图片
的url以及图片的name) 队列2 存放的是图片的url以及name 消费者从队列2当中请求图片的url地
址并下载图片
翻页: page=0为第一页, 以此类推
创建3个生产者线程, 5个消费者线程
消费者 如果出现堵塞状态 不要用加锁 容易出现堵塞或者是死锁 同过判断或者是其他的逻辑
去解决。通过 try 、catch来处理, 然后出现异常 break退出
import os
import threading
from urllib import request
from urllib import parse
import requests
import queueheaders = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ''Chrome/87.0.4280.141 Safari/537.36', 'referer': 'https://pvp.qq.com/ '
}# 定义生产者
class Producer(threading.Thread):def __init__(self, page_queue, image_queue, *args, **kwargs):super(Producer, self).__init__(*args, **kwargs) # ?self.page_queue = page_queueself.image_queue = image_queuedef run(self) -> None: # q.empty() True 队列是空的 not Falsewhile not self.page_queue.empty():page_url = self.page_queue.get()res = requests.get(page_url, headers=headers)result = res.json()datas = result['List']for data in datas:image_urls = extract_images(data)name = parse.unquote(data['sProdName'])dirpath = os.path.join('image', name)if not os.path.exists(dirpath):os.mkdir(dirpath)# 把图片的url放到队列当中for index, image_url in enumerate(image_urls):self.image_queue.put({'image_url': image_url, 'image_path': os.path.join(dirpath, '%d.jpg' % (index + 1))})# 定义消费者
class Consumer(threading.Thread):def __init__(self, image_queue, *args, **kwargs):super(Consumer, self).__init__(*args, **kwargs)self.image_queue = image_queuedef run(self) -> None:while True:try:image_obj = self.image_queue.get(timeout=10)# 获取图片的url 和下载的路径image_url = image_obj.get('image_url')image_path = image_obj.get('image_path')# 下载图片try:request.urlretrieve(image_url, image_path)print(image_path, '下载完成')except:print('下载失败')except:breakdef extract_images(data):image_urls = []for x in range(1, 9):image_url = parse.unquote(data['sProdImgNo_%d' % x]).replace('200', '0')image_urls.append(image_url)return image_urlsdef main():# 创建页数的队列(队列一)page_queue = queue.Queue(10)# 创建图片队列(队列二)image_queue = queue.Queue(1000)# 目标url 翻页的for x in range(0, 3):page_url = 'https://apps.game.qq.com/cgi-bin/ams/module/ishow/V1.0/query/workList_inc.cgi?activityId=2735&sVerifyCode=ABCD&sDataType=JSON&iListNum=20&totalpage=0&page={page}&iOrder=0&iSortNumClose=1&iAMSActivityId=51991&_everyRead=true&iTypeId=2&iFlowId=267733&iActId=2735&iModuleId=2735&_=1611144188371'.format(page=x)# 把页数的url放到队列当中page_queue.put(page_url)# 定义三个生产者线程for x in range(3):th = Producer(page_queue, image_queue)th.start()# 定义五个消费者线程for x in range(5):th = Consumer(image_queue)th.start()if __name__ == '__main__':main()
python多线程案例相关推荐
- python 多进程_说说Python多线程与多进程的区别?
公众号新增加了一个栏目,就是每天给大家解答一道Python常见的面试题,反正每天不贪多,一天一题,正好合适,只希望这个面试栏目,给那些正在准备面试的同学,提供一点点帮助! 小猿会从最基础的面试题开始, ...
- 教你控制Python多线程中线程数量
前言 前段时间学习了python的多线程爬虫,当时爬取一个图片网站,开启多线程后,并没有限制线程的数量,也就是说,如果下载1000张图片,会一次性开启1000个子线程同时进行下载 现在希望控制线程数量 ...
- Python多线程原理与实现
Date: 2019-06-04 Author: Sun Python多线程原理与实战 目的: (1)了解python线程执行原理 (2)掌握多线程编程与线程同步 (3)了解线程池的使用 1 线程基本 ...
- python多线程教程_Python多线程编程教程【2小时学会】
Python多线程编程教程[2小时学会] 中级共14课 从0开始学习python多任务编程,想了解python高并发实现,从基础到实践,通过知识点 + 案例教学法帮助你想你想迅速掌握python多任务 ...
- Python多线程编程基础1:为什么要使用线程
多线程技术的引入并不仅仅是为了提高处理速度和硬件资源利用率,更重要的是可以提高系统的可扩展性(采用多线程技术编写的代码移植到多处理器平台上不需要改写就能立刻适应新的平台,可以也可以简单地通过增加处理器 ...
- python多线程返回值问题重写Thread类的run方法
python多线程使用 文章目录 python多线程使用 一.案例 二.说明 1.针对第一种是有返回值的 ,可以通过future.result() 去拿到每个线程返回值 2.无返回值问题 3.我们可以 ...
- Python多线程编程详解,文章比较长,需耐心浏览
文章目录 前言 创建多线程 守护线程 线程实例 零基础Python学习资源介绍 一.Python所有方向的学习路线 二.Python学习软件 三.Python入门学习视频 四.Python练习题 五. ...
- python简单实例-python简单案例
广告关闭 腾讯云双11爆品提前享,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高满返5000元! 一个简单的python资讯采集案例,列表页到详情页,到数据保存,保存为txt文档, ...
- Python 多线程卖票问题
Python 多线程卖票问题 在学习多线程的时候,我们经常要学习到多窗口售票这一经典案例,今天我们将用Python语言写一个简单易懂的售票程序,帮助大家学习理解 有以下要求: 第一.不能出现打印出现混 ...
最新文章
- HTTP报文简单介绍
- 【Flutter】Future 异步编程 ( 简介 | then 方法 | 异常捕获 | async、await 关键字 | whenComplete 方法 | timeout 方法 )
- 功率曲线k值_什么叫离心泵的流量——功率曲线?它们之间有什么关系?
- MooTools1.3.1 API(Core)学习及试译(三)——Types(二)
- java算法在工作,我在北京找工作(三):java实现算法2 直接插入排序+不可变类...
- wms智能仓储系统不可缺少?
- j剑指offer面试题[33]-把数组排成最小的数
- 使用Web Service Interface. (转)
- 第三节: 串口通信(用CubeMX学习STM32)
- office完全卸载工具
- 渗透测试工程师(实习生)面试题目
- macBook笔记本音乐播放器没声音
- 巴塞罗那2019-20赛季球队大名单
- windbg命令解释
- python多个函数_请教:一个类中可以定义多个同名函数?
- python批量拷贝数据脚本_使用python来玩转ensp~3-写个批量备份配置文件脚本
- SAS(五)建立SAS数据集的方法及导出数据
- 使用进程池抓取猫眼数据
- 动态规划--基本思路理念
- python编写存储过程_存储过程 - msjaxuexi - 博客园
热门文章
- 关于比特,位,字,字节的关系
- workLog: 用seqkit快速进行简单的抗体NGS测序数据分析
- 安装maxscale实现MariaDB高可用及读写分离
- Windows Socket套接字(一)
- jmeter-性能测试9-测试场景与执行
- 软件开发工具【八】 之 Eclipse工作台
- Leetcode——565. Array Nesting
- 访问ChatGPT(openai)出现Access denied(拒绝访问)或则429 You are being rate limited.(429 您受到速率限制)
- 常用的基于内容的推荐算法实现原理
- Handbook of MusicPsychology 音乐心理学手册 ( 多纳德·霍杰斯 Donald.A.Hodges) 笔记