如何使用Python+Selenium循环遍历多页批量下载Excel文件
问题根因
- 循环内放置了仅第一页存在的
hideMoreRelatedOccupations按钮点击逻辑,从第二页开始找不到该元素就会抛异常,被裸except捕获后直接误判为无更多页面,终止循环 - 全程使用
implicitly_wait隐式等待,仅能在查找元素时生效,无法覆盖下载触发、翻页重绘时的DOM稳定等待,容易出现元素未加载完成就执行操作的报错 - 裸
except会拦截所有类型的异常(元素不存在、点击被遮挡、请求未完成等),全部判定为翻页结束,逻辑判断存在严重漏洞 - 触发Excel下载时未配置浏览器下载参数,默认弹出的下载保存弹窗会遮挡页面元素,导致后续点击操作失败
修复要点
- 将仅第一页需要执行的「折叠相关职业」操作移出循环,仅在首次进入结果页执行一次
- 移除裸异常捕获,单独判断下一页按钮的存在、可点击状态作为循环终止条件
- 替换隐式等待为显式等待,每次操作前等待目标元素处于可交互状态,翻页后等待新一页结果加载完成再执行后续操作
- 配置Chrome浏览器启动参数,指定下载目录、禁用下载弹窗,避免弹窗遮挡元素
- 每次触发下载后增加短等待,确认下载请求发起完成后再执行翻页操作
修复后参考代码
from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.support.ui import Select, WebDriverWait from selenium.webdriver.support import expected_conditions as EC from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.common.by import By import os # 配置基础参数 state = 'oklahoma' rent_to_own = 'rent to own' download_path = os.path.abspath("./excel_downloads") # 自定义Excel保存目录 os.makedirs(download_path, exist_ok=True) # 配置Chrome下载选项,禁止弹窗 chrome_options = webdriver.ChromeOptions() prefs = { "download.default_directory": download_path, "download.prompt_for_download": False, "download.directory_upgrade": True, "safebrowsing.enabled": True } chrome_options.add_experimental_option("prefs", prefs) driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=chrome_options) driver.maximize_window() wait = WebDriverWait(driver, 15) # 显式等待最长15秒 # 初始搜索流程 driver.get('https://www.careeronestop.org/toolkit/jobs/find-businesses.aspx') industry = wait.until(EC.presence_of_element_located((By.ID, "txtKeyword"))) industry.send_keys(rent_to_own) location = wait.until(EC.presence_of_element_located((By.ID, "txtLocation"))) location.send_keys(state) wait.until(EC.element_to_be_clickable((By.ID, "btnSubmit"))).click() def web_scrape(): # 首次页面筛选操作,仅执行一次 more_drawer = wait.until(EC.element_to_be_clickable((By.XPATH, "//div[@class='more-drawer']//a[contains(@href, 'Desfillall=y')]"))) more_drawer.click() get_50 = Select(wait.until(EC.presence_of_element_located((By.ID, 'ViewPerPage')))) get_50.select_by_value('50') filter_description = wait.until(EC.element_to_be_clickable((By.XPATH, "//ul[@class='filters-list']//a[contains(@href, 'descfilter=Furniture')]"))) filter_description.click() # 第一页专属:折叠相关职业模块,仅点一次 first_50 = wait.until(EC.element_to_be_clickable((By.XPATH, "//div[@id='relatedOccupations']//a[@onclick='hideMoreRelatedOccupations()']"))) first_50.click() page_num = 1 while True: # 下载当前页Excel download_excel = Select(wait.until(EC.presence_of_element_located((By.ID, 'ResultsDownload')))) download_excel.select_by_value('Excel') print(f"第{page_num}页Excel已触发下载") # 短等待确认下载请求发起 driver.implicitly_wait(2) # 判断是否存在下一页按钮 try: next_page = wait.until(EC.element_to_be_clickable((By.XPATH, "//div[@class='pagination-wrap']//a[@class='next-page']"))) except: print("所有页面下载完成,无更多分页") break # 点击下一页,等待新页面加载 next_page.click() wait.until(EC.staleness_of(next_page)) # 等待旧页面元素失效,确认翻页完成 page_num +=1 web_scrape() driver.quit()
内容的提问来源于stack exchange,提问作者bazinga183
相关产品推荐
相关产品推荐

