使用Python中的Selenium按类名查找元素

87

如何筛选具有相同类的元素?

<html>
  <body>
    <p class="content">Link1.</p>
  </body>
</html>
<html>
  <body>
    <p class="content">Link2.</p>
  </body>
</html>
8个回答

91

您可以尝试使用find_elements_by_class_name方法,通过查找所有 class = "content" 的元素来获取列表:

a = driver.find_elements_by_class_name("content")

然后您可以单击要查找的链接。


4
它会返回该类的所有元素还是仅返回第一个找到的元素? - keerthan kumar
15
如果你马上会重新赋值,为什么要将a初始化为空列表呢? - user124384
3
@keerthankumar 这将返回所有元素的列表。要获取第一个,请使用“find_element_by_class_name”。 - zvi
7
在Selenium 4.3.0版本中,find_element_by_*find_elements_by_*已被移除,请使用find_element代替。您可以在此处查看所有变更日志。 - Parampreet Rai
2
@PeterMortensen 你仍然可以使用 find_elements(By.CLASS_NAME, 'foo') 来获取元素列表。 - Brian Leishman
显示剩余3条评论

51

By.CLASS_NAME尚未提及:

from selenium.webdriver.common.by import By

driver.find_element(By.CLASS_NAME, "content")

以下是可以用作By定位器的属性列表

CLASS_NAME
CSS_SELECTOR
ID
LINK_TEXT
NAME
PARTIAL_LINK_TEXT
TAG_NAME
XPATH


1
谢谢,这对我很有用。使用 find_element_by_class_name 的替代方法对我来说根本行不通,即使我使用了等待。 - sean le roy
但如果它不存在,它会抛出异常。从而干扰测试运行。 - Peter Mortensen
实际上这个问题是针对“元素”复数的,所以driver.find_element(By.CLASS_NAME, "content")不能获取所有元素,对吗? - FabricioG

31
根据HTML:

根据HTML:

<html>
    <body>
    <p class="content">Link1.</p>
    </body>
<html>
<html>
    <body>
    <p class="content">Link2.</p>
    </body>
<html>

有两个内容

元素。

所以为了筛选出拥有相同类名即 content 的元素并创建一个列表,您可以使用以下任一定位策略

  • 使用 class_name

elements = driver.find_elements_by_class_name("content")
使用 css_selector:
 elements = driver.find_elements_by_css_selector(".content")
  • 使用 xpath

    elements = driver.find_elements_by_xpath("//*[@class='content']")
    

  • 理想情况下,要单击该元素,您需要诱导WebDriverWait等待visibility_of_all_elements_located(),并且您可以使用以下任一定位器策略

    • 使用CLASS_NAME

    elements = WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.CLASS_NAME, "content")))
    
  • 使用 CSS_SELECTOR

    elements = WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, ".content")))
    
    使用XPATH:
    elements = WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "//*[@class='content']")))
    
  • 注意: 您需要添加以下导入:

  • from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    

    参考文献

    您可以在以下几个讨论中找到一些相关的内容:


    1
    既没有类名也没有 CSS 选择器起作用,不知道为什么,但是 XPath 起了作用,非常感谢。 - Timeler
    a comment中得知:"find_element_by_*find_elements_by_*在Selenium 4.3.0中已被移除,请使用find_element代替。" - Peter Mortensen

    14

    12

    3

    第一个答案已被弃用,其他答案只返回一个结果。以下是正确的答案:

    driver.find_elements(By.CLASS_NAME, "content")
    

    是的,他们错过了复数形式的“elements”。然而,find_elements 本身已经被弃用 - Peter Mortensen
    “第一个答案”是什么意思?是指得分最高的答案还是时间上最早的答案?相对位置的参考不可靠,因为它们取决于视图(投票/最旧/活跃)以及接受答案的更改和随时间的变化(对于投票、活跃和接受状态)。 - Peter Mortensen
    公平地说,在其中一个答案中没有被忽略。 - Peter Mortensen

    0
    在Python中,Selenium提供了一个名为find_elements_by_class_name的方法,用于查找具有相同类名的元素。该方法返回一个匹配提供的类名的所有元素的列表。
    假设你想要找到所有具有类名为"content"的段落(

    )。以下是你可以做到这一点的方法:

    ```python from selenium import webdriver # 初始化驱动程序 driver = webdriver.Firefox() # 替换为你选择的浏览器驱动程序
    # 导航到你的网页 driver.get('https://www.softwaretestingsapiens.com/finding-elements-by-class-name-with-selenium-in-python/')
    # 通过类名查找元素 elements = driver.find_elements_by_class_name('content')
    for el in elements: print(el.text) ```
    这个脚本将打印出具有类名为"content"的每个

    标签内的文本。在你的情况下,它应该打印出"Link1."和"Link2."。

    请记住,Selenium需要一个特定的驱动程序来与所选择的浏览器进行交互。Firefox需要geckodriver,在上述脚本运行之前需要先安装它。
    另外,请记住,find_elements_by_class_name返回一个列表,即使只有一个匹配项。如果你确定只有一个感兴趣的元素,请使用find_element_by_class_name(注意'element'中没有's')直接获取WebElement。
    最后,建议在你的脚本中添加一些错误处理,以处理元素未找到的情况。这将使你的代码更健壮,更易于调试。
    祝你编码愉快!

    0
    问题与“元素”复数有关,大多数是为元素而设计的。 等待元素,然后迭代每个元素:
    selectableEls = WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.CLASS_NAME, "content")))
    for el in selectableEls:
        print(el)
    

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接