如何在 Python 上按 class 名称正确查找元素?硒相关

How to correctly find elements by class name on Python? Selenium related

我正在尝试在 this page 上自动化一个流程,根据它的 html 代码,在点击位于该页面右上角的钱包按钮后,它部署了 4 个主要钱包选择登录页面。

所有这些钱包共享相同的 class,即 elements__StyledListItem-sc-197zmwo-0 QbTKh,我编写了下面的代码以尝试获取它们的按钮名称(Metamask、Coinbase 钱包...),这里:

driver = webdriver.Chrome(service=s, options=opt) #execute the chromedriver.exe with the previous conditions
driver.implicitly_wait(10)
driver.get('https://opensea.io/') #go to the opensea main page.
WebDriverWait(driver, 3).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="__next"]/div/div[1]/nav/ul/div[2]/li/button'))) #wait for the wallet button to be enabled for clicking
wallet_button = driver.find_element(By.XPATH, '//*[@id="__next"]/div/div[1]/nav/ul/div[2]/li/button') 
wallet_button.click() #click that wallet button
wallet_providers = driver.find_elements(By.CLASS_NAME, "elements__StyledListItem-sc-197zmwo-0 QbTKh") #get the list of wallet providers
for i in wallet_providers:
    print(i)

编译上面的代码后,我注意到它没有打印任何东西,这是由于 wallet_providers 的空数组,这很奇怪,因为我知道通过调用 find_elements(By.CLASS_NAME, "the_class_name") 然后它将 return 一个包含共享相同元素的数组 class,但在这种情况下它没有这样做。

所以,如果有人能解释我做错了什么,我将不胜感激?最后,我只是想设法点击 Metamask 按钮,它并不总是停留在同一位置,有时它是该列表的第一个元素,有时是第二个...

您正在使用 CLASS_NAME elements__StyledListItem-sc-197zmwo-0 QbTKh,其中包含 space。

在 Selenium 中,具有 space 的 class 名称将不会被解析并会抛出错误。

您没有收到错误的原因是您使用的 find_elements 将 return 网络元素列表或什么都没有。

那么如何解决呢?

删除 space 并放置 . 来制作 CSS_SELECTOR

试试这个:

wallet_providers = driver.find_elements(By.CSS_SELECTOR, ".elements__StyledListItem-sc-197zmwo-0.QbTKh") #get the list of wallet providers

老实说,我们可以有比这更好的定位器,因为这些值 197zmwo-0.QbTKh 似乎是动态生成的。

我宁愿使用这个 CSS:

li[class^='elements__StyledListItem'] span[font-weight]

或这个 xpath:

//li[starts-with(@class,'elements__StyledListItem')]//descendant::span[@font-weight]

此外,您应该这样打印:(这是一种方式,但也有其他方式):

代码:

driver.get("https://opensea.io/")

WebDriverWait(driver, 3).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="__next"]/div/div[1]/nav/ul/div[2]/li/button'))) #wait for the wallet button to be enabled for clicking
wallet_button = driver.find_element(By.XPATH, '//*[@id="__next"]/div/div[1]/nav/ul/div[2]/li/button')
wallet_button.click() #click that wallet button
wallet_providers = driver.find_elements(By.CSS_SELECTOR, "li[class^='elements__StyledListItem'] span[font-weight]") #get the list of wallet providers
for i in wallet_providers:
    print(i.get_attribute('innerText'))

控制台输出:

WalletConnect
MetaMask
Coinbase Wallet
Fortmatic

Process finished with exit code 0

您使用的定位器不够相对,在我第一次检查时,我不知何故没有在 DOM 中找到它们。因此,使用相对定位器重构代码以使代码正常工作。

   driver.get('https://opensea.io/') #go to the opensea main page.
    WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//*[@title='Wallet']"))).click()
    wallets = WebDriverWait(driver, 10).until(EC.visibility_of_all_elements_located((By.XPATH, "//*[@data-testid='WalletSidebar--body']//li")))
    for wallet in wallets:
        print(wallet.text)

输出:

WalletConnect
MetaMask
Popular
Coinbase Wallet
Fortmatic

Process finished with exit code 0

您使用其中包含 space 的 class 名称 elements__StyledListItem-sc-197zmwo-0 QbTKh 来查找元素。实际上,在 Selenium 中我们不能使用 class 名称来定位其中包含 space 的 element/elements。您可以使用 CSS-Selector 而不是 class 名称,并且在 CSS-Selector 中您需要将 class 的 space 替换为 (.) 点。

您可以使用父元素 class 然后使用标签指向所需的元素。 div[class='Blockreact__Block-sc-1xf18x6-0.eOSaGo'] > ul > li