Selenium循环中重复获取首个工厂弹窗数据问题求助
Selenium循环获取工厂弹窗数据重复问题解决
抓取https://modon.gov.sa/ar/Partners/Factories/Pages/default.aspx网站工厂数据时,筛选出12个工厂后,循环点击每个工厂弹出详情弹窗,但每次都获取到首个工厂的数据。原始代码如下:
from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.by import By import time #### CONSTANT ##### URL='https://modon.gov.sa/ar/Partners/Factories/Pages/default.aspx' chrome_driver_path = 'E:\programs\chromedriver-win64\chromedriver.exe' AREA= 'الدمام الأولى' ### TO KEEP THE BROWSER OPEN WHEN SCRIPT IS CRASH ##### chrome_option = webdriver.ChromeOptions() chrome_option.add_experimental_option('detach', True) ##### CREATE THE DRIVER ######### ## LOGIN## driver = webdriver.Chrome(executable_path=chrome_driver_path, options=chrome_option) driver.get(url=URL) driver.implicitly_wait(10) ###### SWLWCTING THE AREA ###### select_area = driver.find_element(by=By.ID, value='select2-ctl00_ctl57_g_0b9a1f17_4953_4478_addd_249c1a935db0_ctl00_ddlICity-container') select_area.click() driver.implicitly_wait(10) dropdown_areas= driver.find_elements(by=By.CSS_SELECTOR, value='.select2-results ul li') for area in dropdown_areas: if area.text == AREA: area.click() break driver.find_element(by=By.CSS_SELECTOR, value='.form-group .btn').click() factories= driver.find_elements(by= By.CSS_SELECTOR, value='.row div .facListItem') driver.implicitly_wait(10) print(len(factories)) for factory in factories: factory_details= dict() factory.click() time.sleep(5) name= driver.find_element(by=By.CSS_SELECTOR, value='.modal-content .modal-header h4') print(name.get_attribute('innerText'))
问题原因
- 元素残留与定位冲突:弹窗关闭后旧元素可能仍留在DOM中,
driver.find_element会优先匹配第一个符合选择器的元素,导致重复获取首个弹窗数据。 - 静态等待不可靠:
time.sleep(5)无法精准同步弹窗加载状态,可能弹窗未完全渲染就执行定位,或旧元素未被清理。 - 元素失效风险:循环中
factories列表的元素可能因页面交互(弹窗弹出/关闭)变为失效元素,引发后续操作异常。
修复方案
- 用显式等待替代静态等待,确保弹窗元素加载完成后再定位。
- 每次获取数据后关闭弹窗,清理DOM中的旧元素。
- 通过索引遍历工厂元素,每次循环重新获取元素,避免失效问题。
修改后的代码
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC #### CONSTANT ##### URL='https://modon.gov.sa/ar/Partners/Factories/Pages/default.aspx' chrome_driver_path = 'E:\programs\chromedriver-win64\chromedriver.exe' AREA= 'الدمام الأولى' ### TO KEEP THE BROWSER OPEN WHEN SCRIPT IS CRASH ##### chrome_option = webdriver.ChromeOptions() chrome_option.add_experimental_option('detach', True) ##### CREATE THE DRIVER ######### driver = webdriver.Chrome(executable_path=chrome_driver_path, options=chrome_option) driver.get(url=URL) wait = WebDriverWait(driver, 10) ###### SELECTING THE AREA ###### select_area = wait.until(EC.element_to_be_clickable((By.ID, 'select2-ctl00_ctl57_g_0b9a1f17_4953_4478_addd_249c1a935db0_ctl00_ddlICity-container'))) select_area.click() dropdown_areas = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '.select2-results ul li'))) for area in dropdown_areas: if area.text == AREA: area.click() break wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.form-group .btn'))).click() # 等待工厂列表加载完成 wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '.row div .facListItem'))) # 通过索引遍历,每次重新获取工厂元素避免失效 factory_count = len(driver.find_elements(By.CSS_SELECTOR, '.row div .facListItem')) for i in range(factory_count): factories = driver.find_elements(By.CSS_SELECTOR, '.row div .facListItem') factory = factories[i] factory.click() # 等待弹窗标题加载完成,确保获取当前弹窗元素 name_element = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.modal-content .modal-header h4'))) print(name_element.get_attribute('innerText')) # 关闭弹窗并等待完全消失 close_btn = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.modal-header .close'))) close_btn.click() wait.until(EC.invisibility_of_element_located((By.CSS_SELECTOR, '.modal-content')))
内容的提问来源于stack exchange,提问作者abdelrahman mohammed
相关产品推荐
相关产品推荐

