
本文介绍使用Selenium自动化获取网页中需水平滚动才能显示的全部表头列名,核心思路是模拟用户点击右滚动按钮,逐次加载并提取新出现的元素,直至滚动条宽度归零。
本文介绍使用selenium自动化获取网页中需水平滚动才能显示的全部表头列名,核心思路是模拟用户点击右滚动按钮,逐次加载并提取新出现的`
在爬取如JODI Data Table Viewer这类基于JavaScript动态渲染的表格时,常见问题在于:初始HTML仅包含可视区域内的列(如前14列),其余列需通过水平滚动触发懒加载——此时DOM结构会动态更新,直接调用find_elements无法一次性捕获全部<th class="TVItemColHeader">。<p>解决该问题的关键在于<strong>主动驱动滚动行为,并在每次滚动后重新定位最新列头</strong>。目标页面的滚动控件位于固定位置:<code><td id="hScrollTD">内包含多个<code><img alt="如何完整获取动态滚动表格中的所有列名(以JODI Data为例)" >标签,其中第5个(索引为4)是“向右滚动”按钮,而第4个(索引为3)的width属性实时反映剩余未显示区域宽度(单位为像素)。当该值降为0时,即表示所有列均已加载完毕。
以下是完整、健壮的实现方案:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
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
# 配置驱动(推荐使用webdriver-manager自动管理)
chrome_driver_path = r'C:\Users\user\Downloads\chromedriver-win64\chromedriver-win64\chromedriver.exe'
service = Service(chrome_driver_path)
options = webdriver.ChromeOptions()
options.add_argument('--start-maximized')
# options.add_argument('--headless') # 可选:无界面运行
driver = webdriver.Chrome(service=service, options=options)
wait = WebDriverWait(driver, 30)
try:
driver.get('https://www.php.cn/link/612ba8e9bd06486a09b88ffc221c8738')
# 等待首列头可见,确保表格已加载
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, 'th.TVItemColHeader')))
# 初始化:获取初始可见列名
header_texts = [el.text for el in driver.find_elements(By.CSS_SELECTOR, 'th.TVItemColHeader')]
# 定位滚动控制区
scroll_td = driver.find_element(By.XPATH, "//td[@id='hScrollTD']")
while True:
# 获取当前滚动条剩余宽度(字符串,如 "120")
scroll_width_elem = scroll_td.find_element(By.XPATH, "./img[4]")
scroll_width = scroll_width_elem.get_attribute('width')
# 若宽度为0或不可解析,退出循环
if not scroll_width or int(scroll_width) <= 0:
break
# 点击右滚动按钮(第5个img)
scroll_right_btn = scroll_td.find_element(By.XPATH, "./img[5]")
scroll_right_btn.click()
# 等待新列头出现(关键:避免因渲染延迟导致漏采)
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'th.TVItemColHeader:last-child')))
# 提取最新一列(滚动后新增的最右列)
last_header = driver.find_element(By.CSS_SELECTOR, 'th.TVItemColHeader:last-child')
header_texts.append(last_header.text)
# 可选:添加微小延迟,增强稳定性(尤其在网络较慢时)
time.sleep(0.3)
print(f"成功获取 {len(header_texts)} 列标题:")
print(header_texts)
finally:
driver.quit()✅ 关键要点说明:
-
滚动检测机制可靠:依赖
<img alt="如何完整获取动态滚动表格中的所有列名(以JODI Data为例)" >的width属性比监听scrollLeft或offsetWidth更稳定,因其由服务端直接控制; -
动态等待不可或缺:使用
WebDriverWait配合presence_of_element_located确保新列已渲染完成再读取,避免空值或旧值; -
增量采集策略高效:每次只取
last-child,避免重复抓取或列表去重开销; -
异常防护建议:生产环境应增加超时计数、滚动失败重试及
StaleElementReferenceException捕获逻辑。
⚠️ 注意事项:
- 该网站可能对高频请求做反爬限制,如需批量采集,请添加合理延时或使用代理池;
- 若页面结构更新(如
id或img索引变化),需同步调整XPath路径; -
chromedriver版本须与Chrome浏览器主版本严格匹配,否则易触发SessionNotCreatedException。
通过上述方法,你将能稳定、完整地获取JODI等动态表格的全部时间序列列名(如 Jan2002, Dec2023, Jan2024 …),为后续全量数据解析打下坚实基础。

















