金天牛

导航

selenium并发请求的实现-第二篇

前言

上篇我们介绍了如何用多协程asyncio来实现并发,本篇我们使用多线程threading和多进程multiprocessing来实现并发。

正文

一、同步请求代码优化

第一步,还是使用原来同步请求百度的代码,增加了浏览器启动时的一些参数options.add_argument('--no-sandbox') 和options.add_argument('--disable-dev-shm-usage'),用以避免沙箱权限和共享内存冲突问题。

 1 import time
 2 from selenium import webdriver
 3 from selenium.webdriver.common.by import By
 4 from selenium.webdriver.chrome.options import Options
 5 
 6 
 7 def sync_search_baidu(key_word: str):
 8     """实际的搜索逻辑"""
 9     options = Options()
10     # options.add_argument('--headless') # 启用无头模式
11     options.add_argument('--disable-gpu')  # 禁用GPU加速
12     options.add_argument('--no-sandbox')
13     options.add_argument('--disable-dev-shm-usage')
14     driver = webdriver.Chrome(options=options)
15     driver.maximize_window()  # 最大化窗口
16     search_result = []
17     try:
18         driver.get("https://www.baidu.com")
19         driver.find_element(By.ID, "kw").send_keys(key_word)
20         driver.find_element(By.ID, "su").click()
21         time.sleep(3)
22         search_results = driver.find_elements(By.XPATH, "//div[@id='content_left']//h3//p/span/span")
23         search_result = [result.text for result in search_results]
24     except Exception as e:
25         search_result.append(f"Error occurred while searching for '{key_word}': {e}")
26     finally:
27         driver.quit()
28     return search_result

二、使用线程池的方式来调用

第二步,使用线程池来调用上面函数,支持并发

1 from concurrent.futures import ThreadPoolExecutor
2 
3 
4 def thread_search_baidu(key_word: str):
5     with ThreadPoolExecutor(max_workers=10) as executor:
6         # 在线程池中执行同步的Selenium操作
7         return executor.submit(sync_search_baidu, key_word).result()

第三步,使用线程池测试线程并发

1 def client_test_thread(key_words: list):
2     with ThreadPoolExecutor(max_workers=10) as executor:
3         futures = [executor.submit(thread_search_baidu, key_word) for key_word in key_words]
4         return [future.result() for future in futures]
5 
6 if __name__ == '__main__':
7     key_words = ['面积最大的国家', '死亡人数最多的战役', '化学元素共有多少种']
8     results = client_test_thread(key_words)
9     print(results)

三、使用多进程来调用 

第二步,使用多进程调用上面的函数

通过 Pool.map 实现自动任务分配,比手动管理 Process 更高效可靠。

 1 import os
 2 from multiprocessing import Pool, Manager
 3 
 4 
 5 def multiprocess_search(keywords: list):
 6     """多进程并发控制器"""
 7     max_workers = min(len(keywords), os.cpu_count() - 1)
 8     with Pool(processes=max_workers) as pool:  # 根据关键词数量创建进程池
 9         search_results = pool.map(sync_search_baidu, keywords)  # 自动分配任务
10     return search_results

第三步,直接调用上面的多进程函数

1 if __name__ == '__main__':
2     key_words = ['面积最大的国家', '死亡人数最多的战役', '化学元素共有多少种']
3     results = multiprocess_search(key_words)
4     print(results)

 

 

posted on 2025-06-05 12:02  金天牛  阅读(62)  评论(0)    收藏  举报