如何用Selenium和Python自动选择含EUR的网页下拉列表项
解决方案:自动选择含EUR的搜索下拉选项
核心问题修正
你的代码在选择EUR下拉选项时存在几个关键问题,同时还有逻辑分支、等待方式的不合理之处,以下是针对性调整:
1. 替换硬等待为显式等待
time.sleep()依赖固定时长,稳定性差,改用WebDriverWait等待元素加载完成,确保操作时机正确。
2. 修正EUR选项定位逻辑
Firefox对XPath的matches()语法支持有限,改用contains()定位包含"EUR"的下拉项;同时要定位到可点击的父链接元素,避免点击无效。
3. 修复代码分支问题
原代码仅当cname == "TietoEVRY Oy"时执行核心逻辑,但当前stock_list里是"Nordea Bank Ab",导致逻辑永远不会触发,需去掉该条件判断。
4. 补全变量定义
原代码中old_csv1在使用前未定义,会引发报错,需增加文件存在性判断和默认值处理。
修正后的完整代码
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 import pandas as pd import os import time print("Starting stock script") p = "C:/Users/apskaita3/Finansų analizės ir valdymo sprendimai, UAB/Rokas Toomsalu - Power BI analitika/Integracijos/1_Public comapnies analytics/2. Nasdaq Helsinki/Nasdaq_historical_prices" stock_list = [ {"name": "Nordea Bank Ab", "csv_name": "C:/Users/apskaita3/Finansų analizės ir valdymo sprendimai, UAB/Rokas Toomsalu - Power BI analitika/Integracijos/1_Public comapnies analytics/Databasesets/Nasdaq_historical_prices/NDA-FI.csv"} ] for i in stock_list: csv_name = i['csv_name'] print(f"Starting iteration {i}") cname = i['name'] # 初始化Firefox驱动 driver = webdriver.Firefox(executable_path=r'C:/Users/apskaita3/Documents/geckodriver.exe', service_log_path="C:/Users/apskaita3/Downloads/geckodriver.log") driver.maximize_window() driver.get("https://www.nasdaqomxnordic.com/shares/historicalprices") # 设置起始日期 fromDate = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "FromDate"))) fromDate.click() fromDate.clear() fromDate.send_keys("2006-01-01") # 输入股票名称并等待下拉列表加载 inputElement = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "instSearchHistorical"))) inputElement.send_keys(cname) # 等待含EUR的下拉选项出现并点击 wait = WebDriverWait(driver, 10) eur_option = wait.until(EC.element_to_be_clickable((By.XPATH, "//div[contains(text(), 'EUR')]/parent::a"))) eur_option.click() # 等待页面加载完成,切换调整后价格并导出CSV WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "showAdjusted"))).click() WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "exportExcel"))).click() # 等待下载完成(根据网络情况调整时长) time.sleep(8) # 处理下载的CSV文件 download_dir = "C:/Users/apskaita3/Downloads/" accepted_extensions = ["csv"] filenames = [fn for fn in os.listdir(download_dir) if fn.split(".")[-1] in accepted_extensions and "-2006-01-01" in fn] if not filenames: print("未找到下载的CSV文件") driver.close() continue a1 = filenames[0] try: old_csv1 = pd.read_csv(os.path.join(download_dir, a1), sep=';', skiprows=1) except pd.errors.EmptyDataError: old_csv1 = pd.DataFrame(columns=['Date', 'Bid', 'Ask', 'Opening price','High price','Low price','Closing price', 'Average price','Total volume','Turnover','Trades']) # 读取现有CSV文件,处理格式兼容问题 if os.path.exists(csv_name): try: new_csv1 = pd.read_csv(csv_name, sep=';') if 'sep=' in new_csv1.columns.tolist(): new_csv1 = pd.read_csv(csv_name, sep=';', skiprows=1) else: new_csv1 = pd.read_csv(csv_name, sep=',') except Exception as e: print(f"读取现有CSV出错: {e}") new_csv1 = pd.DataFrame(columns=old_csv1.columns) else: new_csv1 = pd.DataFrame(columns=old_csv1.columns) # 合并数据并去重 new_df1 = pd.concat([old_csv1, new_csv1]).reset_index(drop=True) new_df1.columns = old_csv1.columns new_df1['Trades'] = new_df1['Trades'].replace(" ", "", regex=True) new_df1 = new_df1.sort_values('Date', ascending=False).drop_duplicates(subset='Date') # 删除多余列 if 'Unnamed: 11' in new_df1.columns.tolist(): del new_df1['Unnamed: 11'] # 保存更新后的数据 new_df1.to_csv(csv_name, index=False) print("数据更新完成") # 清理下载的临时文件 for e in os.listdir(download_dir): if "-2006-01-01" in e: os.remove(os.path.join(download_dir, e)) driver.close() time.sleep(3)
关键调整说明
- 显式等待:所有元素操作前通过
WebDriverWait等待元素可交互,避免页面加载延迟导致的报错。 - 有效定位:用
//div[contains(text(), 'EUR')]/parent::a定位EUR选项的父链接,确保点击操作有效触发页面跳转。 - 逻辑修复:移除针对特定股票的判断分支,让代码对
stock_list中所有股票生效。 - 鲁棒性优化:增加文件存在性判断、异常捕获,避免首次运行或文件格式异常时崩溃。
- 去重逻辑:指定按
Date列去重,确保历史数据不会重复存储。
内容的提问来源于stack exchange,提问作者Zymantas
相关产品推荐
相关产品推荐

