新闻中心 分类>>

如何使用 Selenium 正确获取篮球参考网站球员名单元素列表

2026-01-01 00:00:00
浏览次数:
返回列表

本文详解如何通过 selenium 精准定位并获取动态加载的 html 表格中所有球员行元素,重点解决因页面未就绪或 xpath 不精确导致 `find_elements` 返回空列表的问题。

在使用 Selenium 抓取 Basketball-Reference 等结构化体育数据网站时,一个常见误区是:直接调用 find_elements_by_xpath 而未等待目标内容加载完成,或使用过于宽泛/不稳定的 XPath 表达式(如 //tr/td[@data-stat="player"]),导致匹配失败或返回空列表。

例如,原始代码:

players_list = driver.find_elements_by_xpath('//tr/td[@data-stat="player"]')
print(len(players_list))  # 常常输出 0,即使页面上明显存在该列

问题根源有二:

  1. 时机问题: 是异步渲染或依赖 JS 动态注入的,页面 GET 完成后 DOM 可能尚未就绪;
  2. 定位粒度问题://tr/td[@data-stat="player"] 匹配的是
  3. ;而 find_elements 若返回的是分散的 行为单位抓取,再从中提取所需 和空行) players_rows = driver.find_elements(By.XPATH, "//table[@id='roster']/tbody/tr[.//td[@data-stat='player']]") print(f"成功找到 {len(players_rows)} 名球员") # 示例:提取每位球员姓名(位于 data-stat="player" 的 td 内) for i, row in enumerate(players_rows[:3]): # 打印前3名验证 name_cell = row.find_element(By.XPATH, ".//td[@data-stat='player']") print(f"{i+1}. {name_cell.text.strip()}")

    ⚠️ 注意事项:

    • 避免使用 time.sleep() 替代 WebDriverWait —— 效率低且不可靠;
    • //table[@id='roster']/tbody/tr 默认包含表头行(
    中无 data-stat),因此建议加过滤条件 [.//td[@data-stat='player']] 确保只取有效数据行;
  4. 若需处理分页或懒加载内容,请额外检查是否存在“Show More”按钮并触发点击;
  5. 生产环境建议添加异常处理(如 TimeoutException, NoSuchElementException)提升鲁棒性。
  6. 通过结合精准 XPath + 显式等待 + 语义化元素层级选择,即可稳定获取动态表格中的完整球员列表,彻底规避“长度为 0”的陷阱。

    单元格,而非整行
    ,不仅语义不清,还可能因表格嵌套、隐藏行(如注释、分隔符)干扰匹配结果。

    ✅ 正确做法是:

    • 优先利用唯一 ID 定位父容器(如 //table[@id='roster']);
    或文本,逻辑更健壮;
  7. 强制显式等待(WebDriverWait),确保目标表格已存在于 DOM 中。
  8. 以下是兼容 Selenium 4.17+ 的推荐实现(find_element_by_* 已全面弃用):

    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
    
    driver = webdriver.Firefox()
    driver.get("https://www./link/7f5667890e56de28cb734293df7d2c73")
    
    # 等待 roster 表格整体加载完成(比等待单个 td 更可靠)
    wait = WebDriverWait(driver, 10)
    wait.until(EC.presence_of_element_located((By.ID, "roster")))
    
    # 定位 roster 表格的所有数据行(排除 

搜索