connie_tong

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
统计
 

场景:目标抓取1万条数据

执行过程如下:

请求url

得到相应

从相应中提取内容

存到本地

按照逻辑是线性过程,效率太低

可采用异步操作,可考虑3种方式:多线程,多进程,协程

1.快速学会多线程

2.快速学会多进程

3.线程池和进程池

4.拔光新发地

5.协程

6.多任务异步协程实现

7.aiohttp模块详解

8.扒光一本小说

9.综合训练-抓取一部电影

进程是资源单位,每一个进程至少要有一个线程

线程是执行单位

多线程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# 线程,进程
# 进程是资源单位,每一个进程至少要有一股线程
# 线程执行单位
 
# 启动每一个程序默认都会有一股主线程
 
# def func():
#     for i in range(1000):
#         print("func",i)
#
# if __name__ == "__main__":
#     func()
#     for i in range(1000):
#         print("main",i)
 
# 多线程
from threading import Thread  # 多线程类
#
#
# def func():
#     for i in range(1000):
#         print("第一个线程", i)
#
#
# def func_sec():
#     for ts2 in range(1000):
#         print("第二个线程:", ts2)
#
#
# if __name__ == "__main__":
#     # 调用多线程方法,创建线程,给线程安排任务
#     t = Thread(target=func())
#     # 多线程状态为可以开始工作状态,具体的执行时间由CPU决定
#     t.start()
#     # 创建第二个线程
#     t2 = Thread(target=func_sec())
#     t2.start()
#     for i in range(1000):
#         print("主线程", i)
 
# 多线程第二套写法:第二套写法比较主流
 
 
# 写一个类,继承Thread方法,那么这个类也是多线程类
class MyThread(Thread):
    # run方法重写,固定的
    def run(self):
        for i in range(1000):
            print('第一个子线程', i)
 
 
if __name__ == '__main__':
    thread_first = MyThread()
    # thread_first.run() 这个不能这样调用,调用后,就是单线程
    # 开启线程
    thread_first.start()
    for i in range(1000):
        print('主线程', i)

 多进程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 相对于多线程而言,多进程实际用的比较少,因为开辟进程比线程消耗资源要多,耗费内存,不推荐多进程
 
from multiprocessing import Process
 
def func():
    for a in range(1000):
        print("子进程", a)
 
         
if __name__ == '__main__':
 
    p = Process(target=func())
    p.start()
 
    for b in range(1000):
        print("主进程", b)

 线程池和进程池

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 线程池:一次性开辟一些线程,我们用户直接给线程池提交任务,线程任务的调度交给线程池来完成
# 开辟一个50个线程池,
# ThreadPoolExecutor是线程池,ProcessPoolExecutor是进程池
 
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
 
def func(name):
    for i in range(1000):
        print(name, i)
 
 
if __name__ == '__main__':
    # 创建线程池,创建一个由50个线程组成的池程池
    with ThreadPoolExecutor(50) as t:
        # 例如有1万个任务
        for i in range(100):
            # 要给线程池提交任务,给线程传送参数,url等
            t.submit(func,name=f"线程{i}")
    # 等待线程池的任务全部执行完成,才继续执行(这叫守护的概念)
    print("123")

 

posted on   connie_tong  阅读(75)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端
 
点击右上角即可分享
微信分享提示