使用By.LINK_TEXT定位按钮时Selenium抛出元素未找到异常
问题:Selenium定位Yahoo期权页面日期按钮失败
在Yahoo财经的KO期权页面,目标日期按钮的HTML结构如下:
<button class="tertiary-btn fin-size-small menuBtn tw-justify-center rounded rightAlign svelte-xhcwo" data-ylk="elm:inpt;elmt:menu;itc:1;sec:qsp-options;slk:date-select;subsec:date" type="button" aria-label="May 24, 2024" aria-haspopup="listbox" data-type="date" data-rapid_p="14" data-v9y="1"> <div class="icon fin-icon inherit-icn sz-medium svelte-21xhfv"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M16.59 8.59 12 13.17 7.41 8.59 6 10l6 6 6-6z"></path> </svg> </div> <span class=" textSelect svelte-q648fa">May 24, 2024</span> </button>
执行以下Selenium代码时抛出TimeoutException(底层为NoSuchElementError):
browser = webdriver.Firefox() browser.get("https://finance.yahoo.com/quote/KO/options") # The option expiraiton date will change based on when this script runs option_expiration_date = "May 24, 2024" wait = WebDriverWait(browser, 20) field = wait.until(EC.visibility_of_element_located((By.LINK_TEXT, option_expiration_date))) elem = browser.find_element(By.LINK_TEXT, option_expiration_date) elem.click()
报错栈信息:
Message=Message: Stacktrace: RemoteError@chrome://remote/content/shared/RemoteError.sys.mjs:8:8 WebDriverError@chrome://remote/content/shared/webdriver/Errors.sys.mjs:193:5 NoSuchElementError@chrome://remote/content/shared/webdriver/Errors.sys.mjs:511:5 dom.find/<<@chrome://remote/content/shared/DOM.sys.mjs:136:16 Source=C:\Users\Leave\source\repos\Selenium Demo\Selenium Demo\src\demoPackage\yahooFinance.py StackTrace: File "C:\Users\Leave\source\repos\Selenium Demo\Selenium Demo\src\demoPackage\yahooFinance.py", line 18, in yahooFinance field = wait.until(EC.visibility_of_element_located((By.LINK_TEXT, option_expiration_date))) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Leave\source\repos\Selenium Demo\Selenium Demo\src\mainPackage\main.py", line 17, in <module> (Current frame) yahooFinance() selenium.common.exceptions.TimeoutException: Message: Stacktrace: RemoteError@chrome://remote/content/shared/RemoteError.sys.mjs:8:8 WebDriverError@chrome://remote/content/shared/webdriver/Errors.sys.mjs:193:5 NoSuchElementError@chrome://remote/content/shared/webdriver/Errors.sys.mjs:511:5 dom.find/<<@chrome://remote/content/shared/DOM.sys.mjs:136:16
定位失败原因
By.LINK_TEXT定位方式不适用:该定位方式仅针对<a>标签的链接文本,而目标元素是<button>标签,完全不符合匹配规则。- 文本层级问题:日期文本实际嵌套在
<button>内部的<span>标签中,LINK_TEXT无法识别非链接元素内部的文本内容。
解决方法
方法1:使用XPATH定位(推荐)
通过匹配按钮的aria-label属性或内部文本精准定位:
browser = webdriver.Firefox() browser.get("https://finance.yahoo.com/quote/KO/options") option_expiration_date = "May 24, 2024" wait = WebDriverWait(browser, 20) # 方式1:匹配aria-label属性 elem = wait.until(EC.element_to_be_clickable((By.XPATH, f"//button[@aria-label='{option_expiration_date}']"))) elem.click() # 方式2:匹配内部span的文本 elem = wait.until(EC.element_to_be_clickable((By.XPATH, f"//button[contains(.//span, '{option_expiration_date}')]"))) elem.click()
方法2:使用CSS_SELECTOR定位
利用元素的专属属性进行定位:
browser = webdriver.Firefox() browser.get("https://finance.yahoo.com/quote/KO/options") option_expiration_date = "May 24, 2024" wait = WebDriverWait(browser, 20) # 方式1:匹配aria-label属性 elem = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, f"button[aria-label='{option_expiration_date}']"))) elem.click() # 方式2:匹配data-type属性(如果页面中该属性唯一) elem = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[data-type='date']"))) elem.click()
方法3:遍历元素匹配文本(不推荐,效率低)
先获取所有按钮元素,再筛选文本匹配的目标:
browser = webdriver.Firefox() browser.get("https://finance.yahoo.com/quote/KO/options") option_expiration_date = "May 24, 2024" wait = WebDriverWait(browser, 20) buttons = wait.until(EC.presence_of_all_elements_located((By.TAG_NAME, "button"))) for btn in buttons: if btn.text.strip() == option_expiration_date: btn.click() break
内容的提问来源于stack exchange,提问作者nicomp
相关产品推荐
相关产品推荐

