使用Selenium操作NSE India股票页面下拉框及获取表格数据求助
问题描述
我尝试访问页面https://www.nseindia.com/report-detail/eq_security,输入股票代码(例如"INFY")后,需要从下拉框中选择对应的股票。由于股票代码具有唯一性,我尝试用Selenium点击下拉框的首个选项,但程序无法识别到该下拉框。希望有人指导如何点击下拉框的首个选项,并获取下方出现的表格数据。
现有代码
import undetected_chromedriver as uc from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import time import random # 启动undetected Chrome driver = uc.Chrome() driver.get("https://www.nseindia.com/report-detail/eq_security") # 等待页面加载 time.sleep(5) # 步骤1:找到股票代码输入框 symbol_input = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.XPATH, '//*[@id="hsa-symbol"]')) ) # 步骤2:点击输入框并输入'INFY',模拟人类输入速度 symbol_input.click() time.sleep(1) # 模拟人类打字 for char in "INFY": symbol_input.send_keys(char) time.sleep(random.uniform(0.3, 0.6)) # 步骤3:等待下拉框可见 try: # 等待下拉框可见 dropdown = WebDriverWait(driver, 15).until( EC.visibility_of_element_located((By.XPATH, '//ul[contains(@class, "ui-autocomplete")]')) ) # 打印页面源码验证下拉框是否存在 dropdown_html = driver.page_source if 'ui-autocomplete' in dropdown_html: print("✅ 下拉框已显示。") else: print("❌ 下拉框未显示。") # 定位所有下拉选项 dropdown_items = driver.find_elements(By.XPATH, '//ul[contains(@class, "ui-autocomplete")]/li') if dropdown_items: print("✅ 找到下拉选项。") for item in dropdown_items: print(item.text) # 打印所有选项 # 确保首个选项在视图内 driver.execute_script("arguments[0].scrollIntoView();", dropdown_items[0]) # 使用JavaScript点击首个选项 driver.execute_script("arguments[0].click();", dropdown_items[0]) print("✅ 已点击首个下拉选项。") else: print("❌ 未找到下拉选项。") except Exception as e: print(f"❌ 错误: {str(e)}")
解决方案
NSE的下拉框基于jQuery UI Autocomplete实现,原代码存在两个核心问题:输入完成后未触发组件的搜索事件,以及等待条件未确保元素可交互。以下是修复后的实现:
关键优化点
- 触发搜索事件:输入完成后,通过JavaScript触发
input事件,强制组件加载下拉选项 - 更精准的等待条件:使用
EC.element_to_be_clickable确保下拉选项可点击,而非仅可见 - 定位优化:使用更具体的XPath定位下拉框,避免匹配到其他相似元素
- 表格数据提取:点击选项后等待表格加载,提取表格内容
修复后的完整代码
import undetected_chromedriver as uc from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import time import random # 启动浏览器并访问目标页面 driver = uc.Chrome() driver.get("https://www.nseindia.com/report-detail/eq_security") driver.maximize_window() # 等待页面核心元素加载(替代固定sleep) WebDriverWait(driver, 15).until( EC.presence_of_element_located((By.ID, "hsa-symbol")) ) # 定位并激活输入框 symbol_input = driver.find_element(By.ID, "hsa-symbol") symbol_input.click() # 模拟人类输入股票代码 for char in "INFY": symbol_input.send_keys(char) time.sleep(random.uniform(0.2, 0.5)) # 触发input事件,强制下拉框加载选项 driver.execute_script("arguments[0].dispatchEvent(new Event('input'));", symbol_input) # 等待下拉选项可点击 try: # 等待首个下拉选项出现并可点击 first_option = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.XPATH, '//ul[contains(@class, "ui-autocomplete")]/li[@class="ui-menu-item"]')) ) # 点击首个选项 first_option.click() print("✅ 成功选中目标股票") # 等待表格加载并提取数据 table = WebDriverWait(driver, 15).until( EC.visibility_of_element_located((By.XPATH, '//table[@id="equitySecurityTable"]')) ) # 提取表格表头 headers = [th.text.strip() for th in table.find_elements(By.TAG_NAME, "th")] # 提取表格行数据 rows = [] for tr in table.find_elements(By.TAG_NAME, "tr")[1:]: # 跳过表头行 row_data = [td.text.strip() for td in tr.find_elements(By.TAG_NAME, "td")] if row_data: rows.append(row_data) # 打印表格数据 print("\n📊 提取的表格数据:") print("表头:", headers) for idx, row in enumerate(rows, 1): print(f"行{idx}: {row}") except Exception as e: print(f"❌ 执行错误: {str(e)}") finally: # 关闭浏览器 driver.quit()
补充说明
- 避免使用固定
time.sleep(),优先使用WebDriverWait的显式等待,提升稳定性 - 使用
undetected_chromedriver可以绕过NSE的反爬检测,确保访问正常 - 表格数据可根据需求进一步处理(如保存为CSV、Excel等)
内容的提问来源于stack exchange,提问作者chintan patel
相关产品推荐
相关产品推荐

