使用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类名的子元素(对应价格显示区域)。
定位失败的核心原因
- 链式嵌套定位过于脆弱:依赖多层标签的严格嵌套关系,页面结构微小变动(比如新增/修改某个标签)就会导致定位中断,且中间任意元素加载延迟都会引发错误。
- CLASS_NAME定位语法错误:
By.CLASS_NAME不支持同时传入多个类名("ng-tns-c425-30 ng-star-inserted"是两个独立类),Selenium会将其视为一个完整类名查找,自然无法匹配。 - 等待策略不合理:
presence_of_element_located仅判断元素是否存在于DOM中,但元素可能尚未渲染完成或不可见,后续操作仍会失败;且等待的是全局元素,但你的tmp定位路径可能已经出错,导致后续无法找到目标子元素。 - 硬编码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
相关产品推荐
相关产品推荐

