如何使用 Selenium 和 Python 根据前面的文本或类名查找文本

How to find the text based on preceding text or classname using Selenium and Python

我是网络抓取的新手,我一直在为这个特定项目使用 Selenium。在此示例中,我正在抓取网站上的列表,它们的结构如下...

清单 1:

<html>
     <div class="div_class">
          <i class="first_i_class" style="i_style"> ::before </i>
          First Category: 
          <span class="span_class">5</span>
          <br>
          <i class="second_i_class" style="i_style"> ::before </i>
          Second Category: 
          <span class="span_class">3</span>
          <br>
     </div>
</html>

如您所见,第一类和第二类的值相似,因此查找所有元素然后使用正则表达式在这里不起作用。我需要能够根据前面的文本获取文本(在本例中为 5 和 3),在本例中为“First Category:”或“Second Category:”。但是,某些列表可能会跳过某些类别并且看起来像这样...

清单 2:

<html>
     <div class="div_class">
          <i class="third_i_class" style="i_style"> ::before </i>
          Third Category: 
          <span class="span_class">7</span>
          <br>
     </div>
</html>

因为列表之间的类别不同,我认为我不能使用类似的东西:

cat_2_value = browser.find_element_by_xpath("/html/div/span[2][@class='span_class']")

因为 xpath 也会改变。有没有一种方法可以根据

在给定范围内找到文本
  1. 前文(如“第一类:”)或
  2. 前面的<i> class(如“first_i_class”)?

非常感谢任何帮助或澄清问题!

提取文本53等相对于前面的class first_i_class, second_i_class 等,你需要归纳 for the visibility_of_element_located() and you can use the following based :

  • 正在打印 5:

    print(WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//div[@class='div_class']//i[@class='first_i_class']//following::span[1]"))).text)
    
  • 正在打印 3:

    print(WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//div[@class='div_class']//i[@class='second_i_class']//following::span[1]"))).text)
    
  • 注意:您必须添加以下导入:

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

要完成@DebanjanB 的回答,其他选项。如您所愿:

The preceding text (like "First Category: ") :

//span[preceding::text()[1][normalize-space()="First Category:"]]

输出:<span class="span_class">5</span>

The preceding class (like "first_i_class") :

//span[preceding-sibling::i[1][@class="first_i_class"]]

(//span[preceding-sibling::i[1][contains(@class,"i_class")]])[1]

输出:<span class="span_class">5</span>

如果你想获得第二个 span,请将第一个表达式中的“first_i_class”替换为“second_i_class”,或者将最后一个 [1] 更改为 [2] 在第二个表达式中。

要直接获取所有 span 元素,请使用 :

//span[preceding-sibling::i[1][contains(@class,"i_class")]]

输出:<span class="span_class">5</span> <span class="span_class">3</span> <span class="span_class">7</span>