关于多进程,多线程的知识,请自行查询资料补充· ~~~~~~~~~~~
使用多进程:
在python中,使用多进程需要先导包:
from threding import Threaddef work(name):for i in range(1000):print(f"我是线程:{name}, {i}")if __name__ == "__main__":for i in range(10):# 创建 十个线程t = Thread(target=work, args=(f"线程{i}",))t.start()
但是以上不推荐使用,
我们可以模拟一个场景, 例如 你来银行办理业务: 银行提供了5个窗口, 相当于开了5个线程, 而客户就是任务, 如果客户有100个,那么每个人都依次排队去办理业务, 这样我们就要写一个很复杂的检测系统, 所以, 这里直接使用线程池, 使用线程池就可以避免这种情况的发生:
使用线程池可以自动的帮我们来完成检测,调度等操作,我们只需要将任务交给线程池即可。
懒得讲,自己看吧·······
import requests
from lxml import etree
import time
from multiprocessing import Queue # 队列
from multiprocessing import Process # 进程
from concurrent.futures import ThreadPoolExecutorfrom fake_useragent import UserAgentdef get_ua():ua = UserAgent()return ua.randomdef get_img_url(q):""" 获取图片的url, 将url塞入队列 """url = f"https://www.doutupk.com/"resp = requests.get(url, headers={"User-Agent": get_ua()})tree = etree.HTML(resp.content)img_urls = tree.xpath('//li[@class="list-group-item"]/div[@class="pic-content text-center"]/div/a/img[2]/@data-original')for img_url in img_urls:print(img_url)# 把拿到的img_url 塞入队列q.put(img_url) # 固定的q.put("滚蛋吧.没了") # 结束的一个消息def download_img(url):# 如何下载一张图片resp = requests.get(url, headers={"User-Agent": get_ua()})# 文件名称file_name = url.split("/")[-1]with open("./img/" + file_name, mode="wb") as f:f.write(resp.content)print("一张图片下载完成")# 第二个进程. 只负责下载图片
def img_process(q): # 从队列中提取url. 进行下载""" 下载图片 """with ThreadPoolExecutor(10) as t: # ?while 1: # 这边不确定有多少个. 那就一直拿img_url = q.get() # 没有问题. 这里面, get是一个阻塞的逻辑if img_url == '滚蛋吧.没了':break# 在进程中开启多线程(唐马儒)t.submit(download_img, img_url)if __name__ == '__main__':# 准备队列q = Queue() # 主进程 水p1 = Process(target=get_img_url, args=(q,)) # 单独开辟一个内存 阿大p2 = Process(target=img_process, args=(q,)) # 单独开辟一个内存 阿二p1.start()p2.start()p1.join() # 主进程等待子进程跑完p2.join() # 主进程等待子进程跑完