You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Selenium遍历NBA官网下拉菜单时出现list index out of range报错如何解决?

错误根因

  • 隐式等待的作用是全局设置DOM元素查找的最长等待时间,仅需初始化浏览器后声明一次,放在循环中不会生效
  • 切换赛季选项后页面表格会先销毁旧数据再渲染新数据,隐式等待无法识别「表格内容更新完成」的状态,会提前拿到还没渲染完表格的页面源码,导致findAll返回的table列表长度不足,取下标[1]时触发越界报错

解决方案

替换隐式等待为显式等待,每次切换赛季后主动等待目标表格加载完成再解析页面,需要先导入显式等待依赖模块:

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver import Chrome

修改后的完整代码如下:

from selenium.webdriver.support.ui import Select
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver import Chrome
from bs4 import BeautifulSoup
import pandas as pd

player_id = str(1629216)
    
url = 'https://www.nba.com/stats/player/' + player_id + "/shooting/"
browser = Chrome(executable_path='/usr/local/bin/chromedriver')
# 隐式等待仅需全局设置一次,也可删除完全用显式等待替代
browser.implicitly_wait(3)
browser.get(url)

select = Select(browser.find_element_by_xpath('/html/body/main/div/div/div/div[4]/div/div/div/div/div[1]/div[1]/div/div/label/select'))
options = select.options
# 显式等待最长等待时间设置为10秒,可根据网络情况调整
wait = WebDriverWait(browser, 10)

for index in range(0, len(options)):
    select.select_by_index(index)
    # 显式等待:直到页面加载出至少2个class为nba-stat-table__overflow的元素再继续
    wait.until(
        lambda x: len(x.find_elements(By.CLASS_NAME, "nba-stat-table__overflow")) >=2
    )
    # 可选:额外等待页面渲染完成,避免偶发性的旧数据被读取
    browser.execute_script("return document.readyState == 'complete'")

    src = browser.page_source
    parser = BeautifulSoup(src, "lxml") 
    table = parser.findAll("div", attrs = {"class":"nba-stat-table__overflow"})

    headers = table[1].findAll('th')
    headerlist = [h.text.strip() for h in headers[1:]]
    headerlist = [a for a in headerlist if not '\n' in a]
    headerlist.append('AST%')
    headerlist.append('UAST%')

    row_labels = table[1].findAll("td", {"class": "first"})
    row_labels_list = [r.text.strip() for r in row_labels[0:]]

    rows = table[1].findAll('tr')[1:]
    player_stats = [[td.getText().strip() for td in rows[i].findAll('td')[1:]] for i in range(len(rows))]
    
    df = pd.DataFrame(data=player_stats, columns=headerlist, index = row_labels_list)

    print(df)

browser.quit()

补充说明

  • 显式等待会每间隔500ms检查一次条件是否满足,满足就立刻继续执行,比固定时长的隐式等待效率更高,也更适配动态渲染的页面场景
  • 如果遇到偶发的表格内容为空的情况,可以在等待条件中额外增加表格行数量的判断,确保数据已经渲染完成

内容的提问来源于stack exchange,提问作者steezebutter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 11:45:01