Python中delete_loop函数无法循环200次的问题排查请求
问题:递归delete_loop函数仅执行一次就退出
我使用Python结合Selenium编写了自动化脚本,其中通过递归实现的delete_loop函数本应连续运行200次后再继续后续流程,但实际该函数仅执行一次就退出。以下是完整代码:
import time from selenium import webdriver from selenium.common.exceptions import ElementClickInterceptedException from selenium.common.exceptions import ElementNotInteractableException from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from bs4 import BeautifulSoup import csv from selenium.common.exceptions import TimeoutException # Set up the Selenium driver driver = webdriver.Chrome() options = webdriver.ChromeOptions() options.add_argument('--disable-notifications') # Disable notifications driver = webdriver.Chrome(options=options) # Wait for 2 minutes before starting time.sleep(60) driver.get("https://my.zonguru.com/#!/sales-spy") def input_asins(driver): # Load the ASINs from the CSV file asins = [] with open('asins.csv', 'r', encoding='utf-8-sig') as f: reader = csv.reader(f) for row in reader: asins.extend(row) # Input the ASINs asins_to_input = asins[:200] asins = asins[200:] asin_input = driver.find_element(By.CSS_SELECTOR, 'input.asins-counter__input') asin_input.clear() asin_input.send_keys(','.join(asins_to_input)) # Remove the ASINs that have been inputted with open('asins.csv', 'w', newline='') as f: writer = csv.writer(f) writer.writerows([asins]) # Select the 'AU' option country_select = driver.find_element(By.XPATH, '//*[@id="private-content"]/div/div/div/zg-product-tracker/div/div/div/div[2]/div/form/div[3]/div/select') try: country_select.click() except ElementClickInterceptedException: pass except ElementNotInteractableException: pass au_option = driver.find_element(By.CSS_SELECTOR, 'option[value="AU"]') try: au_option.click() except ElementClickInterceptedException: pass except ElementNotInteractableException: pass # Click the submit button submit_button = driver.find_element(By.CSS_SELECTOR, 'button.zg-btn-green') try: submit_button.click() except ElementClickInterceptedException: pass except ElementNotInteractableException: pass def delete_loop(count): if count == 0: return # Click the dropdown dropdown_button = driver.find_element(By.CSS_SELECTOR, '.dropdown > .btn') try: dropdown_button.click() except ElementClickInterceptedException: pass except ElementNotInteractableException: pass # Click the delete delete_button = driver.find_element(By.CSS_SELECTOR, 'a.btn-delete') try: delete_button.click() except ElementClickInterceptedException: pass except ElementNotInteractableException: pass # Click the ok ok_button = driver.find_element(By.CSS_SELECTOR, 'button#alertify-ok') try: ok_button.click() except ElementClickInterceptedException: pass except ElementNotInteractableException: pass # Call the function again with decremented count delete_loop(count - 1) # Continuous loop while True: try: # Load the ASINs input_asins(driver) time.sleep(60) # Click the download download_button = driver.find_element(By.CSS_SELECTOR, 'button.zg-btn-white') try: download_button.click() time.sleep(5) # Wait for 5 seconds to allow the file to download except ElementClickInterceptedException: pass except ElementNotInteractableException: pass delete_loop(200) except Exception as e: time.sleep(10) input_asins(driver) # Close the Selenium driver driver.quit()
问题原因分析
- 元素定位未等待页面刷新:每次删除操作后页面会更新(比如移除一条记录、弹窗关闭),但代码直接用
driver.find_element立即查找元素,未等待页面完成刷新,第二次递归时大概率找不到目标元素,触发未捕获的异常导致递归终止。 - 异常捕获范围不足:
delete_loop仅捕获了点击相关的两种异常,但查找元素时可能抛出NoSuchElementException,该异常未被处理会直接中断整个递归流程。 - 无操作后等待机制:点击删除、确认按钮后,页面需要时间完成响应(如弹窗消失、列表重新渲染),直接递归调用下一次操作,元素还未准备就绪,导致操作失败并中断。
修复方案
1. 替换递归为循环(更稳定)
递归200次虽未达Python默认递归深度限制,但循环更适合这种重复执行的场景,避免递归调用栈的潜在问题。
2. 添加显式等待
用WebDriverWait替代直接查找元素,确保元素加载完成且可交互后再操作,避免页面未刷新导致的元素定位失败。
3. 完善异常捕获
捕获所有Selenium相关异常,避免单个操作失败导致整个流程中断。
修改后的delete_loop函数
from selenium.common.exceptions import NoSuchElementException def delete_loop(count): wait = WebDriverWait(driver, 10) # 设置10秒超时 for _ in range(count): try: # 等待下拉按钮可点击并点击 dropdown_button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.dropdown > .btn'))) dropdown_button.click() # 等待删除按钮可点击并点击 delete_button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'a.btn-delete'))) delete_button.click() # 等待确认按钮可点击并点击 ok_button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'button#alertify-ok'))) ok_button.click() # 等待页面完成刷新(可选,根据实际页面响应调整) time.sleep(1) except (ElementClickInterceptedException, ElementNotInteractableException, NoSuchElementException, TimeoutException): # 遇到异常时跳过当前循环,继续下一次删除 continue
额外优化建议
- 替换
input_asins中的driver.find_element为显式等待,避免固定time.sleep的不稳定; - 主循环中的
time.sleep(60)也可替换为显式等待,等待页面加载完成后再执行后续操作; - 增加日志记录,方便排查每次操作的执行情况。
内容的提问来源于stack exchange,提问作者Brenduan
相关产品推荐
相关产品推荐

