Python多线程运行Selenium Chromedriver仅启动一个实例问题排查
问题原因及解决方案
核心问题:全局共享WebDriver实例
你所有线程都在复用同一个全局driver对象,没有为每个线程创建独立的ChromeDriver实例。不管启动多少线程,所有driver.get()操作都会在同一个浏览器窗口中执行,因此只会看到一个Chromedriver实例。
修复步骤
1. 为每个线程创建独立的WebDriver
修改mainExtractor函数,在函数内部初始化专属的ChromeDriver,彻底抛弃全局driver变量:
def mainExtractor(maxPropertyPrice, minimumComparisonCount=1, pageToStartOn=1): # 每个线程初始化独立的ChromeDriver实例 driver = webdriver.Chrome() # 原有业务逻辑:访问主URL、计算总页数 mainUrl = f"https://www.bayut.com/for-sale/property/dubai/?price_max={maxPropertyPrice}&completion_status=ready" driver.get(mainUrl) totalNumberPages = driver.find_element(By.CLASS_NAME, "ca3976f7") totalNumberPages = math.floor((int(totalNumberPages.text.split(" ")[4].replace(",","")))/24) # ... 其他初始化代码(如图片目录清理) ... # 调用dataScraper时传入当前线程的driver dataScraper(driver, minimumComparisonCount, pageToStartOn, totalNumberPages, maxPropertyPrice) # 线程结束后关闭当前driver driver.quit()
2. 修改dataScraper接收driver参数
让dataScraper使用传入的线程专属driver,不再依赖全局变量:
def dataScraper(driver, minimumComparisonCount=1, pageToStartOn=1, totalNumberPages=1, maxPropertyPrice=1): print("Program going to start extracting from page: ", pageToStartOn) for currentPageExtractorIsOn in range(pageToStartOn, totalNumberPages): bayutPropertiesLink = f"https://www.bayut.com/for-sale/property/dubai/page-{currentPageExtractorIsOn}/?price_max={maxPropertyPrice}&completion_status=ready" print(bayutPropertiesLink) # 使用线程专属driver访问页面 driver.get(bayutPropertiesLink) # ... 原有元素提取、HREF收集代码 ...
3. 修复MongoDB集合清空的冲突问题
原代码中每个线程都会执行collection.delete_many({}),多线程同时清空集合会导致数据冲突。建议将集合清空操作移到主线程,仅执行一次:
# 主线程中先执行集合清空 mongoUri = "mongodb://localhost:27017/dbPropertyAnalysis" client = MongoClient(mongoUri, server_api=ServerApi('1')) db = client["dbPropertyAnalysis"] collection = db["items"] collection.delete_many({}) # 再启动多线程任务 for i in range(4): browserThread = threading.Thread(target=mainExtractor, args=(1000000, 50,2)) browserThread.start()
同时删除mainExtractor内部的MongoDB连接和集合清空代码,避免重复操作。
内容的提问来源于stack exchange,提问作者Commoq
相关产品推荐
相关产品推荐

