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)
浙公网安备 33010602011771号