行者孙Python

奇术秘典篇-Day34|并行合击:并发调度与结果汇总实战

📖 知识点

1. 为什么需要并发调度?

创建多个 Page 后,如果按顺序一个个执行(先跑完 page1 再跑 page2),其实是串行,没提速。用线程(threading)并发,让多个任务同时跑,才真正并行。

串行:A 做完 → 才做 B(耗时相加) 并行:A、B 同时进行(耗时≈最慢那个)

2. 用线程并发调度

import threading

def task(page, url):
    page.get(url)
    # 执行采集逻辑
    return page.title

# 创建线程,分别跑不同Page
t1 = threading.Thread(target=task, args=(page1, "https://www.baidu.com"))
t2 = threading.Thread(target=task, args=(page2, "https://www.bing.com"))
t1.start()
t2.start()
t1.join()
t2.join()

start() 启动线程(并行开始),join() 等待线程结束(确保所有任务完成再汇总)。

3. 结果汇总

线程各自采集后,把结果收集到共享列表:

results = []
def task(page, url):
    page.get(url)
    results.append(f"{url} → {page.title}")   # 各线程把结果加进列表

主线程 join 所有线程后,results 里就汇总了所有 Page 的成果。

完整示例

import threading
from DrissionPage import ChromiumPage

page1 = ChromiumPage()
page2 = ChromiumPage()

results = []   # 汇总结果

def work(page, url):
    page.get(url)
    results.append(f"{url} → 标题:{page.title}")

# 并行合击:两个线程同时跑
t1 = threading.Thread(target=work, args=(page1, "https://www.baidu.com"))
t2 = threading.Thread(target=work, args=(page2, "https://www.bing.com"))
t1.start()
t2.start()

# 等待两个任务都完成
t1.join()
t2.join()

# 汇总输出
for item in results:
    print("📦", item)

⚠️ 易错提醒

  1. 每个线程操作各自的 Page,别让两个线程抢同一个 Page
  2. 共享列表 results 在多线程下追加,注意线程安全(小任务量一般没问题)
  3. 记得 join(),否则主线程可能在子线程完成前就结束

⚔️ Kata 实战任务

任务需求:

  1. 导入 threading 和 ChromiumPage
  2. 创建两个 Page 对象
  3. 编写一个 work 函数:接收 page 和 url,访问后把结果存进共享列表
  4. 用两个线程分别跑两个 Page,并行访问百度、必应
  5. join 等待完成,汇总打印所有结果

参考代码

import threading
from DrissionPage import ChromiumPage

page1 = ChromiumPage()
page2 = ChromiumPage()
results = []

def work(page, url):
    """单个Page的采集任务"""
    page.get(url)
    results.append(f"{url} → 标题:{page.title}")

# 并行合击:两个线程同时施法
t1 = threading.Thread(target=work, args=(page1, "https://www.baidu.com"))
t2 = threading.Thread(target=work, args=(page2, "https://www.bing.com"))
t1.start()
t2.start()

# 等待全部完成
t1.join()
t2.join()

# 结果汇总
print("🎯 并行采集完成,共", len(results), "条结果")
for item in results:
    print("📦", item)

运行输出(示意):

🎯 并行采集完成,共 2 条结果
📦 https://www.baidu.com → 标题:百度一下,你就知道
📦 https://www.bing.com → 标题:Bing

💡 观察:两个任务真正并行,整体耗时约等于最慢那一个,而不是两者相加。这就是并发的威力。

🧠 思考题

  1. 线程里 start() 和 join() 分别做什么?不写 join 会有什么问题?
  2. 如果多个线程要抓同一个网站的多个页面,该怎么分工(每个线程分几页)?相比单线程优势在哪?
‹ 返回目录
🏠首页 Python 📦资源 👤关于我