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

Selenium爬取finq.com股票数据遇List out of index及空DataFrame问题

代码问题修复方案

报错根源

第一个版本List out of index报错

  • 登录流程中切换到了登录iframe,登录成功后没有切回主文档上下文,后续所有页面操作都局限在已无内容的登录iframe内,解析源码时找不到tbody标签,取索引[0]直接触发越界。
  • 固定等待3秒不足以支撑动态行情数据渲染,源码中无目标表格内容。

第二个版本返回空DataFrame

  • 同样存在上下文未切换、数据未加载完成的问题,找不到匹配的tr/td元素。
  • 未校验col的长度,遇到无足够td的行时触发隐式异常,循环终止无数据写入。
  • 未加ignore_index=True参数,append操作未生效。

修正后可运行代码

你需要在登录点击操作后先切回主文档,爬取部分替换为显式等待+Selenium直接定位,不需要转BeautifulSoup解析:

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

# finq credentials
username = "xxxxxx@gmail.com"
password = "xxxxxxxxx"
# initialize the Chrome driver
driver = webdriver.Chrome(executable_path=r'C:\Users\snyder\seaborn-data\chromedriver.exe')
driver.maximize_window()
driver.implicitly_wait(5)
driver.get("https://www.finq.com/en/login")
wait = WebDriverWait(driver, 10)
wait.until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, "iframe[id='login']")))
# 输入账号密码登录
driver.find_element_by_id("login_username").send_keys(username)
driver.find_element_by_id("login_password").send_keys(password)
driver.find_element_by_css_selector("button[id='submit_login']").click()
# 新增:登录成功后切回主文档上下文,这是核心遗漏步骤
driver.switch_to.default_content()

# 登录结果校验
WebDriverWait(driver=driver, timeout=10).until(
    lambda x: x.execute_script("return document.readyState === 'complete'")
)
error_message = "Incorrect username or password."
errors = driver.find_elements_by_class_name("flash-error")
if any(error_message in e.text for e in errors):
    print("[!] 登录失败")
else:
    print("[+] 登录成功")
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.fn-close-popup.popup-actions"))).click()

# ====== 修正后的爬取逻辑 ======
url = "https://live-cosmos.finq.com/trading-platform/#trading/Shares/Global/USA/All/FACEBOOK"
driver.get(url)
# 显式等待表格行加载完成,替换不稳定的固定sleep
wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "tbody tr")))

df = pd.DataFrame(columns=["Instrument", "Sell", "Buy", "Change"])
# 直接用Selenium定位所有行
rows = driver.find_elements_by_css_selector("tbody tr")
for row in rows:
    # 定位当前行的所有td
    cols = row.find_elements_by_tag_name("td")
    # 校验td数量足够再取值,避免越界
    if len(cols) >=4:
        Instrument = cols[0].text.strip()
        Sell = cols[1].text.strip()
        Buy = cols[2].text.strip()
        Change = cols[3].text.strip()
        df = df.append({
            "Instrument":Instrument,
            "Sell":Sell,
            "Buy":Buy,
            "Change":Change
        }, ignore_index=True)

print(df)

额外注意事项

  • 如果目标数据还是渲染在独立iframe中,可在打开行情页后,用显式等待找到对应iframe再切换进入后再定位元素。
  • 原代码中重复导入了webdriver、WebDriverWait,修正后的代码已经清理了冗余导入。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 16:09:04