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

使用Selenium-Python无法找到指定div标签的原因求助

无法用Selenium-Python定位股票价格标签的问题与解决思路

问题概述

尝试使用Selenium-Python获取某只股票价格时,始终无法定位到id为stock-quote-tablet-phone的div标签,已尝试多种元素定位方式均未成功,需分析原因并提供解决办法。

现有代码

class SeleniumDriver:
    def __init__(self):
        self.webdriver = webdriver.Chrome("chromedriver", options=options)
        self.webdriver.get("https://www.avanza.se/min-ekonomi/innehav.html")

        time.sleep(30)  # 留时间让用户登录账户
        self.webdriver.get(AZELIO)
        print("Checkpoint")

        time.sleep(5)
        self.anchor = (
            self.webdriver.find_element(By.TAG_NAME, "aza-app")
            .find_element(By.TAG_NAME, "aza-shell")
            .find_element(By.TAG_NAME, "div")
            .find_element(By.TAG_NAME, "main")
            .find_element(By.TAG_NAME, "div")
            .find_element(By.TAG_NAME, "aza-stock")
            .find_element(By.TAG_NAME, "aza-subpage")
            .find_element(By.TAG_NAME, "div")
        )

    def getPrice(self):
        self.tmp = (
            self.anchor.find_element(By.TAG_NAME, "div")
            .find_element(By.TAG_NAME, "aza-pull-to-refresh")
            .find_elements(By.TAG_NAME, "div")[0]
            .find_element(By.TAG_NAME, "div")
            .find_element(By.TAG_NAME, "aza-page-container")
            .find_element(By.TAG_NAME, "aza-page-container-inset")
            .find_element(By.TAG_NAME, "section")
            .find_element(By.TAG_NAME, "div")
            .find_elements(By.TAG_NAME, "div")[0]
            .find_element(By.TAG_NAME, "aza-instrument-chart")
            .find_element(By.TAG_NAME, "div")
            .find_element(By.TAG_NAME, "div")
        )

        WebDriverWait(self.webdriver, 10).until(
            EC.presence_of_element_located((By.ID, "stock-quote-tablet-phone"))
        )

        self.price = self.tmp.find_element(
            By.CLASS_NAME, "ng-tns-c425-30 ng-star-inserted"
        )
        print(self.price.get_attribute("innerHTML"))

        print(self.tmp.get_attribute("innerHTML"))


testDriver = SeleniumDriver()
testDriver.getPrice()

目标元素说明

目标元素为id是stock-quote-tablet-phone的div标签,其内部包含带有ng-tns-c425-30和ng-star-inserted类名的子元素(对应价格显示区域)。

定位失败的核心原因

  1. 链式嵌套定位过于脆弱:依赖多层标签的严格嵌套关系,页面结构微小变动(比如新增/修改某个标签)就会导致定位中断,且中间任意元素加载延迟都会引发错误。
  2. CLASS_NAME定位语法错误:By.CLASS_NAME不支持同时传入多个类名("ng-tns-c425-30 ng-star-inserted"是两个独立类),Selenium会将其视为一个完整类名查找,自然无法匹配。
  3. 等待策略不合理:presence_of_element_located仅判断元素是否存在于DOM中,但元素可能尚未渲染完成或不可见,后续操作仍会失败;且等待的是全局元素,但你的tmp定位路径可能已经出错,导致后续无法找到目标子元素。
  4. 硬编码sleep不可靠:time.sleep()是固定等待时间,无法适应页面加载的波动情况,可能出现等待不足或过长的问题。

解决办法

1. 简化定位逻辑,直接通过ID定位容器

目标div有唯一IDstock-quote-tablet-phone,直接用ID定位即可,无需多层嵌套:

# 替换原有的tmp定位和等待逻辑
quote_container = WebDriverWait(self.webdriver, 15).until(
    EC.visibility_of_element_located((By.ID, "stock-quote-tablet-phone"))
)

2. 正确定位带多类名的元素

使用CSS_SELECTOR替代CLASS_NAME来匹配多个类名:

self.price = quote_container.find_element(
    By.CSS_SELECTOR, ".ng-tns-c425-30.ng-star-inserted"
)

3. 用显式等待替代硬编码sleep

移除所有time.sleep(),改用WebDriverWait等待关键元素加载,提升稳定性:

# 登录后的页面跳转等待示例
WebDriverWait(self.webdriver, 20).until(
    EC.url_contains(AZELIO.split("/")[-1])  # 等待URL跳转到目标股票页面
)

4. 检查是否存在iframe(可选)

如果目标元素位于iframe内,需先切换到iframe再查找元素:

# 假设iframe有唯一ID或其他定位方式
iframe = WebDriverWait(self.webdriver, 10).until(
    EC.presence_of_element_located((By.ID, "target-iframe-id"))
)
self.webdriver.switch_to.frame(iframe)
# 之后再定位元素
quote_container = WebDriverWait(self.webdriver, 15).until(
    EC.visibility_of_element_located((By.ID, "stock-quote-tablet-phone"))
)
# 操作完成后切回主文档
self.webdriver.switch_to.default_content()

修改后的完整代码示例

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
import time

AZELIO = "你的目标股票页面URL"

class SeleniumDriver:
    def __init__(self):
        options = webdriver.ChromeOptions()
        # 可添加必要的options配置,如无头模式等
        self.webdriver = webdriver.Chrome("chromedriver", options=options)
        self.webdriver.get("https://www.avanza.se/min-ekonomi/innehav.html")

        # 留时间让用户登录账户
        time.sleep(30)
        self.webdriver.get(AZELIO)
        print("Checkpoint")
        # 等待页面跳转完成
        WebDriverWait(self.webdriver, 20).until(
            EC.url_contains(AZELIO.split("/")[-1])
        )

    def getPrice(self):
        # 直接定位目标容器,等待元素可见
        quote_container = WebDriverWait(self.webdriver, 15).until(
            EC.visibility_of_element_located((By.ID, "stock-quote-tablet-phone"))
        )
        
        # 定位价格元素
        self.price = quote_container.find_element(
            By.CSS_SELECTOR, ".ng-tns-c425-30.ng-star-inserted"
        )
        print(self.price.get_attribute("innerHTML"))
        print(quote_container.get_attribute("innerHTML"))


testDriver = SeleniumDriver()
testDriver.getPrice()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 17:31:12