为什么 CSS Selector 在等待元素可点击后无法点击元素?

问题描述

请看下面的代码。我认为除了最后一行之外,您几乎可以忽略所有内容

from selenium import webdriver
import os
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import webdriverwait
from selenium.webdriver.support import expected_conditions as EC
import xlsxwriter
from datetime import datetime
import time

chrome_driver = os.path.abspath('C:/Users/ross/Desktop/chromedriver.exe')
browser = webdriver.Chrome(chrome_driver)
browser.get('https://finra-markets.morningstar.com/BondCenter/Default.jsp')

webdriverwait(browser,60).until(EC.element_to_be_clickable((By.CSS_SELECTOR,'#TabContainer > div > div.rtq-tab-wrap > div.rtq-tab-menus-wrap > ul > li:nth-child(3) > a > span'))).click()
webdriverwait(browser,'#firscreener-cusip'))).send_keys("STWD")
webdriverwait(browser,"#ms-finra-advanced-search-form > div.ms-finra-advanced-search-btn > input:nth-child(2)"))).click()
webdriverwait(browser,"#ms-agreement > input"))).click()

webdriverwait(browser,"#ms-finra-search-results > div > div.qs-resultData > div.qs-resultData-body > div.rtq-grid.rtq-grid-auto-h > div.rtq-grid-hd > div > div:nth-child(7) > div"))).click()
time.sleep(2)
webdriverwait(browser,"#ms-finra-search-results > div > div.qs-resultData > div.qs-resultData-body > div.rtq-grid.rtq-grid-auto-h > div.rtq-grid-hd > div > div:nth-child(7) > div"))).click()
time.sleep(2)
whole_chart = webdriverwait(browser,"#ms-finra-search-results > div > div.qs-resultData > div.qs-resultData-body > div.rtq-grid.rtq-grid-auto-h > div.rtq-scrollpanel > div.rtq-grid-scroll"))).text


parent = browser.find_element_by_xpath('//*[@id="ms-finra-search-results"]/div/div[3]/div[1]/div[1]/div[2]/div[2]/div')
count_divs = len(parent.find_elements_by_xpath("./div"))



for row_num in range(1):

    symbol = webdriverwait(browser,"#ms-finra-search-results > div > div.qs-resultData > div.qs-resultData-body > div.rtq-grid.rtq-grid-auto-h > div.rtq-scrollpanel > div.rtq-grid-scroll > div > div:nth-child(" + str(row_num + 1) + ") > div:nth-child(3)"))).text

    maturity = webdriverwait(browser,"#ms-finra-search-results > div > div.qs-resultData > div.qs-resultData-body > div.rtq-grid.rtq-grid-auto-h > div.rtq-scrollpanel > div.rtq-grid-scroll > div > div:nth-child(" + str(row_num + 1) + ") > div:nth-child(7)"))).text

    moody_rating = webdriverwait(browser,"#ms-finra-search-results > div > div.qs-resultData > div.qs-resultData-body > div.rtq-grid.rtq-grid-auto-h > div.rtq-scrollpanel > div.rtq-grid-scroll > div > div:nth-child(" + str(row_num + 1) + ") > div:nth-child(8)"))).text

    sandp_rating = webdriverwait(browser,"#ms-finra-search-results > div > div.qs-resultData > div.qs-resultData-body > div.rtq-grid.rtq-grid-auto-h > div.rtq-scrollpanel > div.rtq-grid-scroll > div > div:nth-child(" + str(row_num + 1) + ") > div:nth-child(9)"))).text

    bond_yield = webdriverwait(browser,"#ms-finra-search-results > div > div.qs-resultData > div.qs-resultData-body > div.rtq-grid.rtq-grid-auto-h > div.rtq-scrollpanel > div.rtq-grid-scroll > div > div:nth-child(" + str(row_num + 1) + ") > div:nth-child(11)"))).text

    if symbol.strip() and maturity.strip() and moody_rating.strip() and sandp_rating.strip() and bond_yield.strip() and moody_rating != "WR" and sandp_rating != "NR":
        webdriverwait(browser,"#ms-finra-search-results > div > div.qs-resultData > div.qs-resultData-body > div.rtq-grid.rtq-grid-auto-h > div.rtq-scrollpanel > div.rtq-grid-scroll > div > div:nth-child(" + str(row_num + 1) + ") > div:nth-child(2) > div > a"))).click()

        webdriverwait(browser,"#TradeHistory_link"))).click()

基本上,我到达此页面https://finra-markets.morningstar.com/BondCenter/BondDetail.jsp?ticker=C724231&symbol=STWD4571190 并且我希望 Selenium 单击其上的“交易历史”链接,因此我引用了选择器“#TradeHistory_link”。出于某种原因,它没有点击,当我尝试只获取文本时,它也不会得到。我还尝试通过在页面上查找“交易历史”然后单击来单击。那没有用。最后,我想可能页面还没有完全加载,所以我尝试在尝试单击“#TradeHistory_link”之前执行 time.sleep(5) 但无济于事。

这是怎么回事?

解决方法

首先尝试使用 visibility_of_element_located 预期条件而不是 element_to_be_clickable。元素并不总是最终将内部文本构建在其中,并且在它变得可点击的那一刻。能见度通常会晚一点。
我还必须提到你的 css 定位器看起来很糟糕。你必须改进它们。

,

该元素位于 iframe 中,这可能是您无法单击它的原因。您需要先切换到该框架,然后 Selenium 才能与其中的元素进行交互。在与该元素交互之前,请尝试添加此行

driver.switch_to.frame(driver.find_element_by_css_selector('#ms-bond-detail-iframe'))

,

Trade History 链接存在于 iframe 中。要访问该链接,您需要先切换到 iframe

使用 WebDriverWait() 并等待 frame_to_be_available_and_switch_to_it() 并使用元素 ID

WebDriverWait(browser,10).until(EC.frame_to_be_available_and_switch_to_it((By.ID,"ms-bond-detail-iframe")))
WebDriverWait(browser,10).until(EC.element_to_be_clickable((By.CSS_SELECTOR,"#tradeHistory_link"))).click()

要从 iframe 中出来,您需要切换到默认内容

browser.switch_to.default_content()