Python Selenium脚本循环中Except分支未执行,仅Try执行后无反应无报错
问题分析与修复:Selenium脚本except块未执行,无法找到目标元素
需求与问题
需求是让Selenium脚本按以下逻辑执行:
- 检查页面是否存在目标元素,存在则点击
- 若不存在,展开收起的子分类、关闭已展开的子分类,再次搜索元素
- 仍未找到则切换到下一个分类,重复流程;所有分类都查完则点击下一页循环,直到找到元素并点击
当前问题:循环中的except部分完全不执行,执行try块后无任何反应,也没有报错输出。
原代码
from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import NoSuchElementException, StaleElementReferenceException import time def onecolumn(): try: ignored_exceptions = (NoSuchElementException, StaleElementReferenceException) WebDriverWait(driver, 5, ignored_exceptions=NoSuchElementException).until(EC.element_to_be_clickable((By.XPATH, f"//div[child::span[text()='{odds}'] and span[text()='{howtobet}']]"))).click() except: pass def separatecolumn(): try: ignored_exceptions = (NoSuchElementException, StaleElementReferenceException) WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.XPATH, f"//div[@class='srb-ParticipantLabel gl-Market_General-cn1 ' and contains(., '{odds}')]/following::span[text() ='{howtobet}']"))).click() except: pass def subcategoryfunction(): subcategories = (WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, 'div.gl-MarketGroupButton_Text ')))) subcategorylist = [] for subcategory in subcategories: text = subcategory.text subcategorylist.append(text) print(text) time.sleep(3) subcategorylist2 = subcategorylist time.sleep(3) driver.refresh() time.sleep(5) for i in range(0, len(subcategorylist2)): subcategoryindex = subcategorylist2[i] try: onecolumn() or separatecolumn() break except: ignored_exceptions = (NoSuchElementException, StaleElementReferenceException,) WebDriverWait(driver, 2, ignored_exceptions=NoSuchElementException).until(EC.element_to_be_clickable((By.XPATH, f"//div[text() ='{subcategoryindex}']"))).click() ############Main################### categories = (WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, 'div.sph-MarketGroupNavBarButton ')))) categorylist = [] for category in categories: text = category.text categorylist.append(text) print(text) time.sleep(1) categorylist2 = categorylist driver.refresh() time.sleep(10) for i in range(1, len(categorylist2)): categoryindex = categorylist2[i] try: subcategoryfunction() break except: ignored_exceptions = (NoSuchElementException, StaleElementReferenceException,) WebDriverWait(driver, 2, ignored_exceptions=NoSuchElementException).until(EC.element_to_be_clickable((By.XPATH, f"//div[text() ='{categoryindex}']"))).click()
问题根源
- 异常被内部吞掉:
onecolumn()和separatecolumn()函数内部用except: pass捕获了所有异常,导致无论是否找到元素,都不会向外抛出异常。外层try块认为函数执行成功,直接触发break终止循环,后续子分类展开逻辑完全无法执行。 - 逻辑判断错误:
onecolumn() or separatecolumn()写法无效,两个函数无返回值(默认返回None),or运算符不会触发第二个函数执行,也无法判断元素是否找到。 - 循环终止逻辑错误:不管元素是否找到,执行完
onecolumn()后直接break,只尝试第一个子分类就终止循环。 - 主循环逻辑缺陷:主循环执行
subcategoryfunction()后直接break,不管该分类是否找到元素,不会切换到下一个分类继续查找。
修复方案
步骤1:修改元素查找函数,抛出异常而非吞掉
让查找函数在找不到元素时抛出异常,外层才能感知失败:
def onecolumn(): ignored_exceptions = (NoSuchElementException, StaleElementReferenceException) WebDriverWait(driver, 5, ignored_exceptions=ignored_exceptions).until( EC.element_to_be_clickable((By.XPATH, f"//div[child::span[text()='{odds}'] and span[text()='{howtobet}']]")) ).click() def separatecolumn(): ignored_exceptions = (NoSuchElementException, StaleElementReferenceException) WebDriverWait(driver, 5, ignored_exceptions=ignored_exceptions).until( EC.element_to_be_clickable((By.XPATH, f"//div[@class='srb-ParticipantLabel gl-Market_General-cn1 ' and contains(., '{odds}')]/following::span[text() ='{howtobet}']")) ).click()
步骤2:修复子分类处理逻辑,绑定查找与展开操作
重新编写subcategoryfunction(),实现「查找→失败→展开子分类→重试→失败→关闭→下一个子分类」的逻辑:
def subcategoryfunction(): # 获取所有子分类文本 subcategories = WebDriverWait(driver, 20).until( EC.visibility_of_all_elements_located((By.CSS_SELECTOR, 'div.gl-MarketGroupButton_Text ')) ) subcategorylist = [sub.text for sub in subcategories] print("子分类列表:", subcategorylist) driver.refresh() time.sleep(5) found = False for sub_name in subcategorylist: # 先尝试查找目标元素 try: onecolumn() found = True break except (NoSuchElementException, StaleElementReferenceException): try: separatecolumn() found = True break except (NoSuchElementException, StaleElementReferenceException): # 找不到元素,展开当前子分类 sub_btn = WebDriverWait(driver, 2).until( EC.element_to_be_clickable((By.XPATH, f"//div[text()='{sub_name}']")) ) # 判断是否已展开(需根据页面实际class调整) if 'gl-MarketGroupButton_Expanded' not in sub_btn.get_attribute('class'): sub_btn.click() time.sleep(1) # 再次尝试查找 try: onecolumn() found = True break except (NoSuchElementException, StaleElementReferenceException): try: separatecolumn() found = True break except (NoSuchElementException, StaleElementReferenceException): # 仍找不到,关闭当前子分类 if 'gl-MarketGroupButton_Expanded' in sub_btn.get_attribute('class'): sub_btn.click() time.sleep(1) # 所有子分类都试过仍找不到,抛出异常给主循环 if not found: raise NoSuchElementException("当前分类下未找到目标元素")
步骤3:修复主循环逻辑,实现分类切换与下一页处理
让主循环在当前分类找不到元素时自动切换到下一个分类;所有分类查完后点击下一页:
############Main################### categories = WebDriverWait(driver, 20).until( EC.visibility_of_all_elements_located((By.CSS_SELECTOR, 'div.sph-MarketGroupNavBarButton ')) ) categorylist = [cat.text for cat in categories] print("分类列表:", categorylist) driver.refresh() time.sleep(10) found = False for cat_name in categorylist[1:]: # 从索引1开始遍历分类 try: # 切换到当前分类 cat_btn = WebDriverWait(driver, 2).until( EC.element_to_be_clickable((By.XPATH, f"//div[text()='{cat_name}']")) ) if 'sph-MarketGroupNavBarButton_Selected' not in cat_btn.get_attribute('class'): cat_btn.click() time.sleep(2) # 处理子分类 subcategoryfunction() found = True break except NoSuchElementException: # 当前分类找不到,继续下一个 continue # 所有分类都查完仍找不到,点击下一页(需替换为实际的下一页选择器) if not found: try: next_page_btn = WebDriverWait(driver, 5).until( EC.element_to_be_clickable((By.CSS_SELECTOR, "你的下一页按钮CSS选择器")) ) next_page_btn.click() time.sleep(5) # 这里可以递归调用主逻辑,或者重新执行整个流程 # 例如:main() (如果把主逻辑封装成函数) except NoSuchElementException: print("已到最后一页,未找到目标元素")
内容的提问来源于stack exchange,提问作者JakeM
相关产品推荐
相关产品推荐

