【问题标题】:Selenium - Get a list of all the elements between two h1 elementsSelenium - 获取两个 h1 元素之间的所有元素的列表
【发布时间】:2017-02-19 22:08:48
【问题描述】:

我有一个网页,其中包含以下 HTML sn-p

<h1> ... </h1>
<p> ... </p>
<p> ... </p>
<h1> ... </h1>
<h2> ... </h2>
<p> ... </p>
<h3> ... </h3>
<p> ... </p> 
<p> ... </p>
<h1> ... </h1>

假设第一个 h1 元素的 xpath 是//*[@id="profile"]/div[2]/div[2]/div/h1[1],最后一个 h1 元素的 xpath 是 //*[@id="profile"]/div[2]/div[2]/div/h1[3],我怎样才能得到一个引用这两个元素之间所有元素的列表?

【问题讨论】:

  • 您可以发布指向该页面的链接吗?在没有看到页面的情况下,我建议您寻找一个包含您想要的所有元素(如果有的话)的父元素,然后从父元素中获取包含的元素。
  • 你能详细说明你为什么要这样做吗?可能有更好的方法。

标签: python python-3.x selenium selenium-webdriver web-scraping


【解决方案1】:

如果您为第一个和第三个 h1 添加一些独特的属性,则以下 xpath 可以工作。

"//*[preceding-sibling::h1[@some unique att] and following-sibling::h1[@some unique att]"

【讨论】:

    【解决方案2】:

    考虑一大块这样的 HTML:

    <body>
        <h1 id="profile"> 1st h1 </h1>
        <p> 1st p </p>
        <p> 2nd p </p>
        <h1> 2nd h1 </h1>
        <h2> 1st h2 </h2>
        <p> 3rd p </p>
        <h3> 1st h3 </h3>
        <p> 4th p </p> 
        <p> 5th p</p>
        <h1 id="profile"> 3rd h1 </h1>
    </body>
    

    您想要的项目有一个(共同的)父元素,即body 元素。因此,通过定位第一个h1,您可以定位该父级。然后您可以找到第一个h1 的所有兄弟姐妹。

    >>> from selenium import webdriver
    >>> from selenium.webdriver.common.keys import Keys
    >>> driver = webdriver.Chrome()
    >>> driver.get('file://c:/scratch/temp.htm')
    >>> parent = driver.find_element_by_xpath('//h1[@id="profile"]/..')
    >>> for child in parent.find_elements_by_xpath('./child::*'):
    ...     child.text, child.get_attribute('id')
    ... 
    ('1st h1', 'profile')
    ('1st p', '')
    ('2nd p', '')
    ('2nd h1', '')
    ('1st h2', '')
    ('3rd p', '')
    ('1st h3', '')
    ('4th p', '')
    ('5th p', '')
    ('3rd h1', 'profile')
    

    在这个循环中child 将包含您似乎想要的引用。您可以使用 get_attribute 返回的内容来忽略您不想要的兄弟姐妹。

    【讨论】:

      【解决方案3】:

      在 C# 中我会做这样的事情

      static int void test(ChromeDriver driver)
          {
              int counter = 0;
              try
              {
                  for (int i = 1; i <= 3; i++)
                  {
                      string getdata = driver.FindElementByXPath("//*[@id=""profile""]/div[2]/div[2]/div/h1[" + i +]").Text;
                          counter++;
      
                  }
              }
              catch
              {
                  return counter;
              }
          }
      

      在循环中通过增加 Xpath 值 +1 来搜索每个元素

      div[2]/div[2]/div/h1[1]
      div[2]/div[2]/div/h1[2]
      div[2]/div[2]/div/h1[3]
      

      对于循环到达它找不到的值时的异常,然后返回计数值。这样您就知道存在 [3] 元素。你可以点击写任何你需要点击任何你想要的人。抱歉,它在 C# 中,但希望逻辑对你有用。

      【讨论】:

        【解决方案4】:

        深度限定的 xPath 是 element location strategy 的反模式,而是考虑以下列表,从以下的目标元素开始,向外而不是自上而下。

        1. 全局唯一项目的 ID 属性
        2. 本地唯一项目的名称属性
        3. 聚焦 xPath 以实现最大控制
        4. 带框架的类名
        5. 内容文本

        前端开发的最佳实践使页面易于使用 Selenium WebDriver 进行自动化测试。

        【讨论】:

          【解决方案5】:

          下面的xpath 可以让你在值之间穿梭。

          //*[preceding-sibling::h1]
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-02-08
            • 1970-01-01
            • 2020-05-10
            • 2017-07-23
            • 2021-07-02
            • 2012-06-07
            • 1970-01-01
            • 2022-12-16
            相关资源
            最近更新 更多