- 简介
- 多线程codingFrame
- 多进程codingFrame
- 线程池与进程池
- 线程池爬取实例(主页url隐了 主要看思路 和如何使用线程池框架)
多线程codingFrame进程是资源单位 线程是执行单位
每一个进程至少有一个线程
启动每一个程序默认都会有一个主线程
# 多线程
from threading import Thread
def func(name):
for i in range(1000):
print(name,i)
if __name__=="__main__":
t1 = Thread(target=func,args=("周杰伦",)) # 创建线程并给线程安排任务,传参必须是元组
t1.start() # 多线程状态为可以开始工作状态,具体的执行时间由CPU决定
t2 = Thread(target=func,args=("蔡依林",)) # 创建线程并给线程安排任务,传参必须是元组
t2.start() # 多线程状态为可以开始工作状态,具体的执行时间由CPU决定
for i in range(1000):
print("main",i)
-----------------------------------------------------------------------------------------------------------------------------------
from threading import Thread
class MyThread(Thread):
def run(self): # 固定的 -> 当线程被执行的时候,被执行的就是run()
for i in range(1000):
print("子线程",i)
if __name__=="__main__":
t = MyThread()
# t.run() # 方法调用了 但是是单线程
t.start() # 开启线程
for i in range(1000):
print("主线程",i)
多进程codingFrame
# 多进程
from multiprocessing import Process
def func():
for i in range(1000):
print("子进程",i)
if __name__=="__main__":
p = Process(target=func)
p.start() # 开启进程
for i in range(1000):
print("主进程",i)
线程池与进程池
# 线程池和进程池
# 线程池:一次性开辟一些线程,我们用户直接给线程池提交任务。任务调度交给线程池完成。
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
def fn(name):
for i in range(100):
print(name,i)
if __name__=="__main__":
# 创建线程池
with ThreadPoolExecutor(50) as t:
for i in range(100):
t.submit(fn,name=f"线程{i}")
# 等待线程池中的任务全部执行完毕,才继续执行(守护)
print("123")
线程池爬取实例(主页url隐了 主要看思路 和如何使用线程池框架)
# 1.如何提取单个页面的数据
# 2.上线程池,多个页面同时抓取
from concurrent.futures import ThreadPoolExecutor
import requests
from lxml import etree
import time
from bs4 import BeautifulSoup as bs
import os
i = 0
writepath = r".pic"+"\"
url = "https://www.xxxxxx.com"
header = {
"User-Agent":"Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11"
}
resp = requests.get(url,headers=header)
resp.close()
# xpath解析主页
html = etree.HTML(resp.text)
# 拿到主页里面的每一个合集页地址
as_ = html.xpath("/html/body/div[2]/div[1]/a/@href")
albumhtml = []
albumpagehtml = []
for href in as_:
# print(url + href[3::])
albumhtml.append(url + href[3::])
# print(albumhtml)
def download_one_album(albumaddress):
n = 1
resp = requests.get(albumaddress,headers=header)
resp.close()
html = etree.HTML(resp.text)
title = html.xpath("/html/body/div[2]/div/div/h4/text()")
foldername = str()
for word in title[0]:
if word!=" " and word != "n":
foldername += word
print(foldername)
os.makedirs(writepath+foldername)
savepath = writepath+foldername
albumas_ = html.xpath("/html/body/div[2]/div/div/div[4]/ul/li/a/@href")
for page in albumas_:
albumpagehtml = albumaddress+page[page.index("?")::]
resp = requests.get(albumpagehtml,headers=header)
resp.close()
page = bs(resp.text, "html.parser") # 拿到页面源码
picpath = page.find("div", class_="container-fluid").find_all("img")
for picp in picpath:
t1 = time.time()
src = picp.get("src") # 拿到所有图像的地址
# 下载图片
img_resp = requests.get(src) # 请求get到所有图像
img_resp.content # 这里拿到的是字节
with open(savepath+"\"+str(n)+".jpg",mode="wb") as p:
p.write(img_resp.content) # 图片内容写入到文件
print(f"成功保存图像:{foldername}/{str(n)}.jpg!")
t2 = time.time()-t1
time.sleep(8)
n += 1
print(f"{foldername}完成!")
if __name__=="__main__":
# 创建线程池
with ThreadPoolExecutor(24) as t:
for url in albumhtml:
t.submit(download_one_album,url)
# 等待线程池中的任务全部执行完毕,才继续执行(守护)
print("全部完成!")



