
本文详解如何在 selenium 自动化中正确处理伦敦证券交易所(lse)等动态网站中延迟渲染、cookie 阻挡及元素不可点击问题,通过显式等待、滚动定位、cookie 接受与 xpath 精准定位,稳定触发 `td.clickable` 元素跳转。
在使用 Selenium 自动化访问 LSE Price Explorer 时,脚本失败的根本原因并非元素选择器错误,而是三重阻断机制叠加:
- Cookie 弹窗拦截:页面首次加载后,遮罩层会阻塞所有交互,必须先接受 Cookie;
- 动态渲染延迟:表格数据由 Angular 异步加载,presence_of_element_located 仅确认 DOM 存在,不保证内容已填充或可交互;
-
Angular 属性变更:如 表明组件处于未就绪状态,此时 td.clickable 虽存在但被禁用。
以下是经过验证的健壮解决方案(适配最新 Chrome + Selenium 4+):
✅ 正确步骤与优化代码
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 from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options import time # 启动配置(无头模式可选,调试建议关闭) options = Options() # options.add_argument("--headless") # 调试时注释此行 options.add_argument("--no-sandbox") options.add_argument("--disable-dev-shm-usage") driver = webdriver.Chrome(options=options) wait = WebDriverWait(driver, 15) # 延长超时至15秒应对慢网 try: driver.get("https://www.php.cn/link/12b71d68d0493e7ac7c5e0558c0a498e") # Step 1: 显式等待并点击 Cookie 接受按钮(关键!) cookie_btn = wait.until( EC.element_to_be_clickable((By.XPATH, "//button[contains(text(), 'Accept') or contains(., 'AGREE')]")) ) cookie_btn.click() time.sleep(1) # 短暂缓冲,确保弹窗完全消失 # Step 2: 等待表格主体加载完成(等待 tbody 中至少一个 tr 渲染) wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "table#price-explorer-results-wrapper tbody tr"))) # Step 3: 定位所有可点击公司名 td(推荐:基于 span 文本更稳定) company_tds = wait.until( EC.presence_of_all_elements_located(( By.CSS_SELECTOR, "td.clickable.instrument-name.gtm-trackable.td-with-link span.ellipsed" )) ) # Step 4: 逐个点击(避免 stale element,每次重新查找) for i in range(min(3, len(company_tds))): # 示例:只点前3个,防超时 # 重新获取最新元素列表(防止 stale) fresh_tds = driver.find_elements(By.CSS_SELECTOR, "td.clickable.instrument-name.gtm-trackable.td-with-link span.ellipsed") if i >= len(fresh_tds): break elem = fresh_tds[i] # 滚动到视口并确保可点击 driver.execute_script("arguments[0].scrollIntoView({block: 'center'});", elem) wait.until(EC.element_to_be_clickable((By.XPATH, f"(//span[@class='ellipsed'])[{i+1}]"))) # 使用 JavaScript 点击(绕过遮挡或 disabled 状态) driver.execute_script("arguments[0].click();", elem) # 等待新页面加载(公司详情页) wait.until(EC.url_contains("/stock/")) print(f"✅ 已跳转至:{driver.current_url}") # 【可选】返回上一页继续循环 driver.back() wait.until(EC.url_contains("price-explorer")) finally: driver.quit()⚠️ 关键注意事项
- 勿依赖固定 XPath:答案中 /html/body/.../tr[1]/td[2]/span 易因页面结构更新而失效,应优先使用 CSS_SELECTOR + 类名组合,辅以 text() 或 contains() 定位;
- *避免 `find_elementsby**:该方法在 Selenium 4+ 中已废弃,统一使用driver.find_elements(By.XXX, "...")`;
- 慎用 time.sleep():仅在极少数异步状态同步场景下作为兜底(如 Cookie 点击后),主流程务必使用 WebDriverWait;
-
处理多窗口:若需在新标签页操作,记得切换句柄:
original_handle = driver.current_window_handle driver.switch_to.window(driver.window_handles[-1]) # ...操作详情页... driver.close() driver.switch_to.window(original_handle)
- 反爬提示:LSE 对高频请求敏感,生产环境建议添加 time.sleep(2–5) 及 User-Agent 轮换。
✅ 总结
成功点击动态 td.clickable 的核心在于:先解封(Cookie)、再等待(真实数据就绪)、后定位(稳定选择器)、最后安全点击(JS 执行)。抛弃“找到即点”的直觉,拥抱显式等待与状态感知,才能让自动化脚本在现代 SPA 网站中稳定运行。










